Package org.apache.click.examples.util

Source Code of org.apache.click.examples.util.DatabaseInitListener$ReloadTask

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.click.examples.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.access.DataDomain;
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.access.DbGenerator;
import org.apache.cayenne.conf.Configuration;
import org.apache.cayenne.conf.ServletUtil;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.query.SelectQuery;
import org.apache.click.examples.domain.Course;
import org.apache.click.examples.domain.Customer;
import org.apache.click.examples.domain.PostCode;
import org.apache.click.examples.domain.StudentHouse;
import org.apache.click.examples.domain.SystemCode;
import org.apache.click.examples.domain.User;
import org.apache.click.examples.quartz.ExampleJob;
import org.apache.click.examples.quartz.SchedulerService;
import org.apache.click.util.ClickUtils;
import org.apache.commons.lang.WordUtils;
import org.quartz.JobDetail;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;

/**
* Provides a database initialization servlet context listener. This listener
* creates a examples database schema using the Cayenne {@link DbGenerator}
* utility class, and loads data files into the database. This class also
* adds an ExampleJob to the Quartz Scheduler.
* <p/>
* This listener also provides a customer reloading task which runs every 15
* minutes.
*
* @author Malcolm Edgar
*/
public class DatabaseInitListener implements ServletContextListener {

    private static final long RELOAD_TIMER_INTERVAL = 1000 * 60 * 5;

    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    private Timer reloadTimer = new Timer(true);

    // --------------------------------------------------------- Public Methods

    /**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();

        ServletUtil.initializeSharedConfiguration(servletContext);

        try {
            DataDomain cayenneDomain =
                Configuration.getSharedConfiguration().getDomain();
            DataMap dataMap = cayenneDomain.getMap("cayenneMap");
            DataNode dataNode = cayenneDomain.getNode("cayenneNode");

            initDatabaseSchema(dataNode, dataMap);

            loadDatabase();

            StdSchedulerFactory schedulerFactory = (StdSchedulerFactory)
                servletContext.getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY);

            SchedulerService schedulerService = new SchedulerService(schedulerFactory);

            loadQuartzJobs(schedulerService);

            reloadTimer.schedule(new ReloadTask(schedulerService), 10000, RELOAD_TIMER_INTERVAL);


        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Error creating database", e);
        }
    }

    /**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent sce) {
        reloadTimer.cancel();
    }

    // -------------------------------------------------------- Private Methods

    /**
     * Create the demonstration database schema using the given Cayenne
     * DataNode and DataMap.
     *
     * @param dataNode the Cayenne DataNode
     * @param dataMap the Cayenne DataMap
     * @throws Exception
     */
    private void initDatabaseSchema(DataNode dataNode, DataMap dataMap)
            throws Exception {

        DbGenerator generator = new DbGenerator(dataNode.getAdapter(), dataMap);
        generator.setShouldCreateFKConstraints(true);
        generator.setShouldCreatePKSupport(true);
        generator.setShouldCreateTables(true);
        generator.setShouldDropPKSupport(false);
        generator.setShouldDropTables(false);

        generator.runGenerator(dataNode.getDataSource());
    }

    /**
     * Load data files into the database
     *
     * @throws IOException if an I/O error occurs
     */
    private void loadDatabase() throws IOException {
        final DataContext dataContext = DataContext.createDataContext();

        // Load users data file
        loadUsers(dataContext);

        // Load customers data file
        loadCustomers(dataContext);

        // Load customers data file
        loadSystemCodes(dataContext);

        // Load post codes data file
        loadPostCodes(dataContext);

        // Load course data file
        loadCourses(dataContext);

        // Load student houses data file
        loadStudentHouses(dataContext);

        dataContext.commitChanges();
    }

    private static void loadFile(String filename, DataContext dataContext,
            LineProcessor lineProcessor) throws IOException {

        InputStream is = ClickUtils.getResourceAsStream(filename, DatabaseInitListener.class);

        if (is == null) {
            throw new RuntimeException("classpath file not found: " + filename);
        }

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(is));

            String line = reader.readLine();
            while (line != null) {
                line = line.trim();

                if (line.length() > 0 && !line.startsWith("#")) {
                    lineProcessor.processLine(line, dataContext);
                }

                line = reader.readLine();
            }
        } finally {
            ClickUtils.close(reader);
        }
    }

    private void loadUsers(final DataContext dataContext) throws IOException {
        loadFile("users.txt", dataContext, new LineProcessor() {
            public void processLine(String line, DataContext context) {
                StringTokenizer tokenizer = new StringTokenizer(line, ",");

                User user = new User();

                user.setUsername(next(tokenizer));
                user.setPassword(next(tokenizer));
                user.setFullname(next(tokenizer));
                user.setEmail(next(tokenizer));

                context.registerNewObject(user);
            }
        });
    }

    private static void loadCustomers(final DataContext dataContext) throws IOException {
        // Load customers data file
        loadFile("customers.txt", dataContext, new LineProcessor() {
            public void processLine(String line, DataContext context) {
                StringTokenizer tokenizer = new StringTokenizer(line, ",");

                Customer customer = new Customer();
                customer.setName(next(tokenizer));
                if (tokenizer.hasMoreTokens()) {
                    customer.setEmail(next(tokenizer));
                }
                if (tokenizer.hasMoreTokens()) {
                    customer.setAge(Integer.valueOf(next(tokenizer)));
                }
                if (tokenizer.hasMoreTokens()) {
                    customer.setInvestments(next(tokenizer));
                }
                if (tokenizer.hasMoreTokens()) {
                    customer.setHoldings(Double.valueOf(next(tokenizer)));
                }
                if (tokenizer.hasMoreTokens()) {
                    customer.setDateJoined(createDate(next(tokenizer)));
                }
                if (tokenizer.hasMoreTokens()) {
                    customer.setActive(Boolean.valueOf(next(tokenizer)));
                }

                dataContext.registerNewObject(customer);
            }
        });
    }

    private void loadSystemCodes(final DataContext dataContext) throws IOException {
        loadFile("system-codes.txt", dataContext, new LineProcessor() {
            public void processLine(String line, DataContext context) {
                StringTokenizer tokenizer = new StringTokenizer(line, ",");

                SystemCode systemCode = new SystemCode();
                systemCode.setName(next(tokenizer));
                systemCode.setValue(next(tokenizer));
                systemCode.setLabel(next(tokenizer));
                systemCode.setOrderBy(Integer.valueOf((next(tokenizer))));

                dataContext.registerNewObject(systemCode);
            }
        });
    }

    private void loadPostCodes(final DataContext dataContext) throws IOException {
        loadFile("post-codes-australian.csv", dataContext, new LineProcessor() {
            public void processLine(String line, DataContext context) {
                if (!line.startsWith("Pcode")) {
                    StringTokenizer tokenizer = new StringTokenizer(line, ",");

                    String postcode = next(tokenizer);
                    String locality = WordUtils.capitalizeFully(next(tokenizer));
                    String state = next(tokenizer);

                    PostCode postCode = new PostCode();
                    postCode.setPostCode(postcode);
                    postCode.setLocality(locality);
                    postCode.setState(state);

                    dataContext.registerNewObject(postCode);
                }
            }
        });
    }

    private void loadCourses(final DataContext dataContext) throws IOException {
        loadFile("courses.txt", dataContext, new LineProcessor() {
            public void processLine(String line, DataContext context) {
                StringTokenizer tokenizer = new StringTokenizer(line, ",");

                Course course = new Course();

                course.setName(next(tokenizer));

                context.registerNewObject(course);
            }
        });
    }

    private void loadStudentHouses(final DataContext dataContext) throws IOException {
        loadFile("student-houses.txt", dataContext, new LineProcessor() {
            public void processLine(String line, DataContext context) {
                StringTokenizer tokenizer = new StringTokenizer(line, ",");

                StudentHouse studentHouse = new StudentHouse();

                studentHouse.setName(next(tokenizer));

                context.registerNewObject(studentHouse);
            }
        });
    }

    private static String next(StringTokenizer tokenizer) {
        String token = tokenizer.nextToken().trim();
        if (token.startsWith("\"")) {
            token = token.substring(1);
        }
        if (token.endsWith("\"")) {
            token = token.substring(0, token.length() - 1);
        }
        return token;
    }

    private static Date createDate(String pattern) {
        try {
            return FORMAT.parse(pattern);
        } catch (ParseException pe) {
            return null;
        }
    }

    private static void loadQuartzJobs(SchedulerService schedulerService) {

        // Create Submission Synchronize Job
        if (!schedulerService.hasJob(ExampleJob.class.getSimpleName())) {
            JobDetail jobDetail = new JobDetail();

            jobDetail.setName(ExampleJob.class.getSimpleName());
            jobDetail.setDescription("Demonstration job write Hello World");
            jobDetail.setJobClass(ExampleJob.class);

            // 5 minute interval
            final long fiveMinutesInMs = 24 * 60 * 60 * 1000;

            schedulerService.scheduleJob(jobDetail, new Date(), null, -1, fiveMinutesInMs);
        }
    }

    // Inner Classes ----------------------------------------------------------

    private static interface LineProcessor {
        public void processLine(String line, DataContext dataContext);
    }

    private static class ReloadTask extends TimerTask {

        private SchedulerService schedulerService;

        public ReloadTask(SchedulerService schedulerService) {
            this.schedulerService = schedulerService;
        }

        @SuppressWarnings("unchecked")
        public void run() {
            DataContext dataContext = null;
            try {
                dataContext = DataContext.createDataContext();

                SelectQuery query = new SelectQuery(Customer.class);
                List<Customer> list = dataContext.performQuery(query);

                if (list.size() < 60) {
                    dataContext.deleteObjects(list);

                    loadCustomers(dataContext);

                    dataContext.commitChanges();
                }

                loadQuartzJobs(schedulerService);

            } catch (Throwable t) {
                t.printStackTrace();

                if (dataContext != null) {
                    dataContext.rollbackChanges();
                }
            }
        }
    }
}
TOP

Related Classes of org.apache.click.examples.util.DatabaseInitListener$ReloadTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.