/* * Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved. * * This file is part of the Jspresso framework. * * Jspresso is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Jspresso is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Jspresso. If not, see <http://www.gnu.org/licenses/>. */ package org.jspresso.framework.tools.viewtester; import java.awt.BorderLayout; import java.util.Locale; import java.util.TimeZone; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import org.apache.commons.cli.BasicParser; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.LocaleUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.access.BeanFactoryLocator; import org.springframework.beans.factory.access.BeanFactoryReference; import org.springframework.beans.factory.access.SingletonBeanFactoryLocator; import org.springframework.context.ApplicationContext; import org.jspresso.framework.application.backend.BackendControllerHolder; import org.jspresso.framework.application.backend.IBackendController; import org.jspresso.framework.application.frontend.IFrontendController; import org.jspresso.framework.binding.IValueConnector; import org.jspresso.framework.model.descriptor.IComponentDescriptor; import org.jspresso.framework.model.entity.IEntity; import org.jspresso.framework.model.entity.IEntityFactory; import org.jspresso.framework.util.swing.SwingUtil; import org.jspresso.framework.view.IView; import org.jspresso.framework.view.descriptor.IViewDescriptor; /** * Generates Jspresso powered component java code based on its descriptor. * * @author Vincent Vandenschrick */ public class ViewTester { private static final Logger LOG = LoggerFactory .getLogger(ViewTester.class); private static final String BEAN_FACTORY_SELECTOR = "beanFactorySelector"; private static final String APPLICATION_CONTEXT_KEY = "applicationContextKey"; private static final String LANGUAGE = "language"; private static final String VIEW_ID = "viewId"; private String beanFactorySelector; private String applicationContextKey; private String language; private String viewId; /** * Starts Code generation for an component. * * @param args * the command line arguments. */ @SuppressWarnings("static-access") public static void main(String... args) { Options options = new Options(); options .addOption(Option.builder(APPLICATION_CONTEXT_KEY) .argName(APPLICATION_CONTEXT_KEY) .required() .hasArg() .desc( "use given applicationContextKey as registered in the Spring BeanFactoryLocator.") .build()); options .addOption(Option.builder(BEAN_FACTORY_SELECTOR) .argName(BEAN_FACTORY_SELECTOR) .hasArg() .desc( "use given resource path to lookup the Spring BeanFactoryLocator. If not set, defaults to beanRefFactory.xml") .build()); options.addOption(Option.builder(VIEW_ID) .argName(VIEW_ID) .required() .hasArg() .desc( "use given view identifier to instantiate and display the view.") .build()); options.addOption(Option.builder(LANGUAGE) .argName(LANGUAGE) .hasArg() .desc( "use given locale to instantiate and display the view.") .build()); CommandLineParser parser = new BasicParser(); CommandLine cmd; try { cmd = parser.parse(options, args); } catch (ParseException ex) { LOG.error("Error parsing command line", ex); HelpFormatter formatter = new HelpFormatter(); formatter.printHelp(ViewTester.class.getSimpleName(), options); return; } final ViewTester tester = new ViewTester(); tester.setBeanFactorySelector(cmd.getOptionValue(BEAN_FACTORY_SELECTOR)); tester .setApplicationContextKey(cmd.getOptionValue(APPLICATION_CONTEXT_KEY)); tester.setViewId(cmd.getOptionValue(VIEW_ID)); tester.setLanguage(cmd.getOptionValue(LANGUAGE)); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { tester.displayView(); } }); } /** * Generates the component java source files. */ @SuppressWarnings("unchecked") public void displayView() { Locale locale; if (language != null) { locale = LocaleUtils.toLocale(language); } else { locale = Locale.getDefault(); } ApplicationContext appContext = getApplicationContext(); IViewDescriptor viewDescriptor = (IViewDescriptor) appContext .getBean(viewId); IFrontendController<JComponent, Icon, Action> mockFrontController = (IFrontendController<JComponent, Icon, Action>) appContext .getBean("applicationFrontController"); IBackendController mockBackController = (IBackendController) appContext .getBean("applicationBackController"); BackendControllerHolder.setSessionBackendController(mockBackController); mockFrontController .start(mockBackController, locale, TimeZone.getDefault()); IView<JComponent> view = mockFrontController.getViewFactory().createView( viewDescriptor, mockFrontController, locale); if (viewDescriptor.getModelDescriptor() != null) { IValueConnector modelConnector = mockBackController.createModelConnector( IValueConnector.MODEL_CONNECTOR_PROPERTY, viewDescriptor.getModelDescriptor()); IEntityFactory entityFactory = mockBackController.getEntityFactory(); modelConnector.setConnectorValue(entityFactory .createEntityInstance(((IComponentDescriptor<IEntity>) viewDescriptor .getModelDescriptor()).getComponentContract())); mockFrontController.getMvcBinder().bind(view.getConnector(), modelConnector); } JFrame testFrame = new JFrame("View tester"); testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); testFrame.getContentPane().setLayout(new BorderLayout()); testFrame.getContentPane().add(view.getPeer(), BorderLayout.CENTER); testFrame.pack(); testFrame.setSize(450, 300); System.setProperty("sun.awt.exception.handler", TesterExceptionHandler.class.getName()); SwingUtil.centerOnScreen(testFrame); testFrame.setVisible(true); } /** * Sets the beanFactorySelector. * * @param beanFactorySelector * the beanFactorySelector to set. */ public void setBeanFactorySelector(String beanFactorySelector) { this.beanFactorySelector = beanFactorySelector; } /** * Sets the applicationContextKey. * * @param applicationContextKey * the applicationContextKey to set. */ public void setApplicationContextKey(String applicationContextKey) { this.applicationContextKey = applicationContextKey; } /** * Sets the language. * * @param language * the language to set. */ public void setLanguage(String language) { this.language = language; } /** * Sets the viewId. * * @param viewId * the viewId to set. */ public void setViewId(String viewId) { this.viewId = viewId; } private ApplicationContext getApplicationContext() { BeanFactoryLocator bfl = SingletonBeanFactoryLocator .getInstance(beanFactorySelector); BeanFactoryReference bf = bfl.useBeanFactory(applicationContextKey); return (ApplicationContext) bf.getFactory(); } /** * Specialized exception handler for the tester event dispatch thread. * * @author Vincent Vandenschrick */ public static class TesterExceptionHandler { /** * Handles a uncaught exception. * * @param t * the uncaught exception. */ public void handle(Throwable t) { LOG.error("An unexpected error occurred.", t); JOptionPane.showMessageDialog(null, t.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } } }