name.martingeisse.admin.customization.Main.java Source code

Java tutorial

Introduction

Here is the source code for name.martingeisse.admin.customization.Main.java

Source

/**
 * Copyright (c) 2011 Martin Geisse
 *
 * This file is distributed under the terms of the MIT license.
 */

package name.martingeisse.admin.customization;

import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import name.martingeisse.admin.WebServerLauncher;
import name.martingeisse.admin.application.ApplicationConfiguration;
import name.martingeisse.admin.application.DefaultPlugin;
import name.martingeisse.admin.customization.incubator.NavigationTabBarFactory;
import name.martingeisse.admin.customization.pagebar.BasicPageBarFactory;
import name.martingeisse.admin.entity.EntityCapabilities;
import name.martingeisse.admin.entity.EntityConfiguration;
import name.martingeisse.admin.entity.component.list.datatable.populator.PopulatorColumnDescriptor;
import name.martingeisse.admin.entity.instance.IEntityInstance;
import name.martingeisse.admin.entity.list.EntityConditions;
import name.martingeisse.admin.entity.property.ExplicitEntityPropertyFilter;
import name.martingeisse.admin.entity.property.SingleEntityPropertyFilter;
import name.martingeisse.admin.entity.schema.ApplicationSchema;
import name.martingeisse.admin.entity.schema.EntityDescriptor;
import name.martingeisse.admin.entity.schema.annotation.AnnotatedClassEntityAnnotationContributor;
import name.martingeisse.admin.entity.schema.annotation.IEntityAnnotatedClassResolver;
import name.martingeisse.admin.entity.schema.naming.IEntityNameMappingStrategy;
import name.martingeisse.admin.entity.schema.naming.PrefixEliminatingEntityNameMappingStrategy;
import name.martingeisse.admin.entity.schema.orm.EntityOrmMapping;
import name.martingeisse.admin.entity.schema.orm.IEntityOrmMapper;
import name.martingeisse.admin.entity.schema.search.IEntitySearchContributor;
import name.martingeisse.admin.entity.schema.search.IEntitySearchStrategy;
import name.martingeisse.admin.navigation.NavigationNode;
import name.martingeisse.admin.navigation.PanelPageNavigationHandler;
import name.martingeisse.admin.navigation.handler.EntityListPanelHandler;
import name.martingeisse.admin.navigation.handler.PopulatorBasedEntityListHandler;
import name.martingeisse.admin.navigation.handlers.UrlNavigationHandler;
import name.martingeisse.common.database.EntityConnectionManager;
import name.martingeisse.common.database.MysqlDatabaseDescriptor;
import name.martingeisse.common.util.GenericTypeUtil;
import name.martingeisse.wicket.autoform.AutoformPanel;
import name.martingeisse.wicket.autoform.annotation.structure.AutoformPropertyOrder;
import name.martingeisse.wicket.autoform.annotation.validation.AutoformAssociatedValidator;
import name.martingeisse.wicket.autoform.annotation.validation.palette.MinIntegerValue;
import name.martingeisse.wicket.autoform.componentfactory.DefaultAutoformPropertyComponentFactory;
import name.martingeisse.wicket.autoform.describe.DefaultAutoformBeanDescriber;
import name.martingeisse.wicket.populator.RowFieldPopulator;

import org.joda.time.DateTimeZone;

import com.google.common.base.CaseFormat;
import com.mysema.query.sql.RelationalPath;
import com.mysema.query.support.Expressions;
import com.mysema.query.types.Ops;
import com.mysema.query.types.Path;
import com.mysema.query.types.Predicate;

/**
 * The main class.
 */
public class Main {

    /**
     * The main method
     * @param args command-line arguments (ignored)
     * @throws Exception on errors
     */
    @SuppressWarnings("unchecked")
    public static void main(final String[] args) throws Exception {

        // --- code generation start ---
        /*
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/phorum?zeroDateTimeBehavior=convertToNull&useTimezone=false", "root", "");
        MetaDataExporter exporter = new MetaDataExporter();
        exporter.setTargetFolder(new File("generated"));
        exporter.setPackageName("phorum");
        exporter.setSerializerClass(MetaDataSerializer.class);
        exporter.setBeanSerializer(new BeanSerializer(true));
        exporter.export(connection.getMetaData());
        connection.close();
        System.exit(0);
        */
        // --- code generation end ---

        //      DatabaseDescriptor mainDatabase = new DatabaseDescriptor();
        //      mainDatabase.setDisplayName("main database");
        //      mainDatabase.setUrl("jdbc:postgresql://localhost/admintest");
        //      mainDatabase.setUsername("postgres");
        //      mainDatabase.setPassword("postgres");
        //      ApplicationConfiguration.addDatabase(mainDatabase);

        // the database
        //      final AbstractDatabaseDescriptor phpbbDatabase = new MysqlDatabaseDescriptor();
        //      phpbbDatabase.setDisplayName("phpBB database");
        //      phpbbDatabase.setUrl("jdbc:mysql://localhost/phpbb");
        //      phpbbDatabase.setUsername("root");
        //      phpbbDatabase.setPassword("");
        //      ApplicationConfiguration.get().addDatabase(phpbbDatabase);

        //
        // The database. Note about "useTimezone=false": This is needed so we can load local dates and
        // datetimes from the database. JDBC uses an inherently broken model here, which we're trying to
        // circumvent. Speaking in Joda-Time terms, the database stores a local date or datetime value,
        // NOT an instant -- that is, the timezone is implicit, not stored. JDBC, however, always
        // wants to convert this to an instant that is expressed as a java.sql.Date or java.sql.Timestamp,
        // i.e. an instant that is represented in UTC, using an implicit timezone whose origin depends
        // on the JDBC driver. To obtain a local value without too much hassle, we set "useTimezone=false"
        // to make this conversion a NOP, i.e. make JDBC assume that the database value is a local value
        // that is to be interpreted as UTC, so the conversion just takes this value and adds "UTC" to it.
        // We then take the value and create a local value as a Joda object by throwing away the "UTC" again.
        //
        // NOTE: This description is specific to MySQL. For other databases, we basically need to do
        // whatever is necessary to read the local value from the database as a local value expressed
        // as a Joda object, circumventing JDBC's stupidity and implicit rules.
        //
        // NOTE: The server stores a server-wide time zone setting. One *could* use that to interpret
        // database values as instants instead of local values. However, (1) this setting cannot be
        // trusted to be correct since it's not used in many places in DB-side time handling (i.e.
        // we might very well have to deal with an incorrectly configured database and existing
        // applications that know how to work around it), and (2) we'll have to deal with values in the
        // DB that are meant as local values, and might even be part of a (local value, time zone) pair.
        // Applying the server time zone to such values would be incorrect. So we'll only deal with the
        // server time zone as much as needed to get rid of it and obtain the local values that are
        // actually stored in the DB tables.
        //
        // If part of the application wants to store an instant in the database -- a quite common task --
        // we'll rather have the application convert it manually, possibly providing access to
        // automatic type conversion (e.g. an implicitly converting ISqlDateTimeTypeInfo). The
        // admin framework should not do this -- it would be an implicit conversion layer that adds
        // confusion, and it would be unclear to the application developer how the time zone used
        // for that conversion is related to the SQL server time zone setting.
        //
        // NOTE: Actually we don't absolutely *need* that parameter for MySQL since it's the default.
        //
        final MysqlDatabaseDescriptor phorumDatabase = new MysqlDatabaseDescriptor();
        phorumDatabase.setDisplayName("Phorum database");
        phorumDatabase.setUrl("jdbc:mysql://localhost/phorum?zeroDateTimeBehavior=convertToNull&useTimezone=false");
        phorumDatabase.setUsername("root");
        phorumDatabase.setPassword("");
        phorumDatabase.setDefaultTimeZone(DateTimeZone.forID("Europe/Berlin"));
        // phorumDatabase.setDefaultTimeZone(DateTimeZone.forID("Europe/London"));
        phorumDatabase.initialize();
        ApplicationConfiguration.get().addDatabase(phorumDatabase);
        EntityConnectionManager.initializeDatabaseDescriptors(phorumDatabase);

        // plugins / capabilities
        ApplicationConfiguration.get().addPlugin(new DefaultPlugin());
        // ApplicationConfiguration.get().addPlugin(new FixedNameEntityReferenceDetector("extensions", "group_id", "extension_groups"));
        ApplicationConfiguration.get().addPlugin(new CustomizationPlugin());
        ApplicationConfiguration.get()
                .addPlugin(new SingleEntityPropertyFilter(1, null, "modificationTimestamp", false));
        ApplicationConfiguration.get()
                .addPlugin(new SingleEntityPropertyFilter(1, null, "modificationUser_id", false));
        ApplicationConfiguration.get()
                .addPlugin(new SingleEntityPropertyFilter(1, "User", "lastLoginAttemptTimestamp", false));
        //      ApplicationConfiguration.get().addPlugin(new GlobalEntityListPresenter("ids", "IDs only", IdOnlyGlobalEntityListPanel.class));
        //      ApplicationConfiguration.get().addPlugin(new GlobalEntityListPresenter("roleList", "Role List", RoleOrderListPanel.class));
        //      ApplicationConfiguration.get().addPlugin(new GlobalEntityListPresenter("popdata", "Populator / DataView", PopulatorDataViewPanel.class));

        final ExplicitEntityPropertyFilter userPropertyFilter = new ExplicitEntityPropertyFilter(2, "User");
        userPropertyFilter.getVisiblePropertyNames().add("id");
        userPropertyFilter.getVisiblePropertyNames().add("name");
        ApplicationConfiguration.get().addPlugin(userPropertyFilter);

        // general parameters
        //      PagesConfigurationUtil.setPageBorderFactory(new name.martingeisse.admin.customization.PageBorderFactory());

        // entity parameters
        EntityConfiguration generalEntityConfiguration = new EntityConfiguration();
        //      generalEntityConfiguration.setEntityNameMappingStrategy(new PrefixEliminatingEntityNameMappingStrategy("phpbb_"));
        IEntityNameMappingStrategy.PARAMETER_KEY.set(new PrefixEliminatingEntityNameMappingStrategy("phorum_"));
        EntityConfiguration.parameterKey.set(generalEntityConfiguration);

        // entity navigation contributors
        /*
        EntityCapabilities.entityNavigationContributorCapability.add(new IEntityNavigationContributor() {
           @Override
           public void contributeNavigationNodes(EntityDescriptor entity, NavigationNode mainEntityInstanceNode) {
        if (entity.getName().equals("settings")) {
           mainEntityInstanceNode.setHandler(new EntityInstancePanelHandler(SettingPanel.class));
        } else {
           mainEntityInstanceNode.setHandler(new EntityInstancePanelHandler(RawEntityPresentationPanel.class));
        }
        mainEntityInstanceNode.getChildFactory().createEntityInstancePanelChild("edit", "Edit", NavigationMountedEntityAutoformPanel.class);
           }
        });
        */

        // test raw entity presentation column order
        //      EntityConfigurationUtil.getGeneralEntityConfiguration().setEntityListFieldOrder(new IEntityListFieldOrder() {
        //         @Override
        //         public int compare(EntityPropertyDescriptor prop1, EntityPropertyDescriptor prop2) {
        //            return prop1.getName().compareTo(prop2.getName());
        //         }
        //      });

        // test entity search support
        EntityCapabilities.entitySearchContributorCapability.add(new IEntitySearchContributor() {

            @Override
            public IEntitySearchStrategy getSearchStrategy(EntityDescriptor entity) {
                return new IEntitySearchStrategy() {
                    @Override
                    public Predicate createFilter(EntityDescriptor entity, String searchTerm) {
                        EntityConditions conditions = new EntityConditions(entity);
                        conditions.addFieldComparison("name", Ops.LIKE, "%" + searchTerm.replace("%", "") + "%");
                        return conditions;
                    }
                };
            }

            @Override
            public int getScore(EntityDescriptor entity) {
                return (entity.getProperties().get("name") == null ? Integer.MIN_VALUE : 0);
            }

        });

        // entity autoforms
        IEntityAnnotatedClassResolver classResolver = new EntityAutoformAnnotatedClassResolver(
                "name.martingeisse.admin.customization.entity");
        EntityCapabilities.entityAnnotationContributorCapability
                .add(new AnnotatedClassEntityAnnotationContributor(classResolver));

        // initialize specific entity code mapping
        IEntityOrmMapper.PARAMETER_KEY.set(new IEntityOrmMapper() {
            @Override
            public EntityOrmMapping map(EntityDescriptor entityDescriptor) {
                try {
                    String baseName = entityDescriptor.getName();
                    String suffix = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, baseName);
                    String className = "phorum.Phorum" + suffix;
                    String qclassName = "phorum.QPhorum" + suffix;
                    return new EntityOrmMapping(entityDescriptor, Class.forName(className), GenericTypeUtil
                            .<Class<? extends RelationalPath<?>>>unsafeCast(Class.forName(qclassName)));
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        // run
        WebServerLauncher.launch();

    }

    /**
     * 
     */
    private static void buildNavigation() {
        final NavigationNode root = null;
        root.setPageBarFactory(new BasicPageBarFactory());
        root.getChildFactory().createChild("home-dummy", "Home", new UrlNavigationHandler("/"));
        final NavigationNode sub1 = root.getChildFactory().createFirstChildHandlerChild("sub-one", "Sub One");
        sub1.getChildFactory().createNavigationFolderChild("s1-sub-one", "s1 Sub One");
        sub1.getChildFactory().createNavigationFolderChild("s1-sub-two", "s1 Sub Two");
        sub1.getChildFactory().createNavigationFolderChild("s1-sub-three", "s1 Sub Three");

        //      sub1sub1.createChild(new BookmarkableEntityListNavigationHandler(TODO_REMOVE_RawEntityListPage.class, "acl_roles").setId("roles").setTitle("ACL: Roles"));
        //      sub1.createChild(new BookmarkableEntityListNavigationHandler(TODO_REMOVE_RawEntityListPage.class, "acl_users").setId("users").setTitle("ACL: Users"));
        //      root.createFolderChild("sub-two", "Sub Two");
        //      root.createFolderChild("sub-three", "Sub Three");
        //      root.createChild(new BookmarkableEntityListNavigationHandler(TODO_REMOVE_RawEntityListPage.class, "acl_users").setId("users1").setTitle("Users-1"));
        //      root.createChild(new BookmarkableEntityListNavigationHandler(TODO_REMOVE_RawEntityListPage.class, "acl_users").setId("users2").setTitle("Users-2"));
        //      root.createChild(new BookmarkableEntityListNavigationHandler(TODO_REMOVE_RawEntityListPage.class, "acl_users").setId("users3").setTitle("Users-3"));

        //      final NavigationNode roles = root.createChild(new GlobalEntityListNavigationHandler("acl_roles").setId("roles").setTitle("Roles"));
        //      roles.createChild(new EntityInstancePresentationNavigationHandler("acl_roles", "default").setId("${id}").setTitle("Instance"));

        //      root.createChild(new BookmarkableEntityListNavigationHandler(TODO_REMOVE_RawEntityListPage.class, "acl_roles").setCanonicalEntityListNode(true));

        //      IEntityListFilter myFilter = new IEntityListFilter() {
        //         @Override
        //         public boolean evaluate(EntityInstance input) {
        //            Object id = input.getId();
        //            if (id instanceof Integer) {
        //               int intId = (Integer)id;
        //               return intId < 15;
        //            }
        //            return true;
        //         }
        //      };
        //      IExpression idCondition1 = new BinaryExpression(new ColumnReference("t", "role_id"), BinaryOperator.LESS_THAN, new IntegerLiteral(15));
        //      IExpression idCondition2 = new BinaryExpression(new ColumnReference("t", "role_id"), BinaryOperator.NOT_EQUAL, new IntegerLiteral(7));
        //      IExpression idConditions = new BinaryExpression(idCondition1, BinaryOperator.AND, idCondition2);
        //      IEntityListFilter myFilter = new EntityListFilter(idConditions);

        /*
        root.getChildFactory().createEntityListPanelChild("acl_roles", "Roles*", MyPopulatorListPanel.class, "acl_roles");
            
        {
           IEntityCellPopulator description = new EntityFieldPopulator("Role Description", "role_description");
           IEntityCellPopulator order = new EntityFieldPopulator("Role Order", "role_order");
           @SuppressWarnings("unchecked")
           IEntityCellPopulator multi = new MultiCellPopulator("Test", new EntityFieldPopulator(null, "role_description"), new EntityFieldPopulator(null, "role_order"));
           root.getChildFactory().createChild("X", "Roles**", new PopulatorBasedEntityListHandler("acl_roles", description, order, multi));
        }
            
        root.getChildFactory().createEntityListPanelChild("roles_all", "Roles", RawEntityListPanel.class, "acl_roles");
            
        {
           Path<Integer> roleId = EntityListFilterUtils.fieldPath(Integer.class, "role_id");
           NumberExpression<Integer> mod2 = Expressions.numberOperation(Integer.class, Ops.MOD, roleId, Expressions.constant(2));
           Predicate even = Expressions.predicate(Ops.EQ, mod2, Expressions.constant(0));
           root.getChildFactory().createEntityListPanelChild("roles_even", "Even", RawEntityListPanel.class, "acl_roles", even);
        }
            
        {
           Path<Integer> roleId = EntityListFilterUtils.fieldPath(Integer.class, "role_id");
           NumberExpression<Integer> mod2 = Expressions.numberOperation(Integer.class, Ops.MOD, roleId, Expressions.constant(2));
           Predicate odd = Expressions.predicate(Ops.EQ, mod2, Expressions.constant(1));
           root.getChildFactory().createEntityListPanelChild("roles_odd", "Odd", RawEntityListPanel.class, "acl_roles", odd);
        }
            
        {
           EntityConditions conditions = new EntityConditions();
           conditions.addFieldComparison("role_id", Ops.LT, 10);
           root.getChildFactory().createEntityListPanelChild("roles_lt10", "<10", RawEntityListPanel.class, "acl_roles", conditions);
        }
            
        //      {
        //         MultiCondition condition = new MultiCondition();
        //         condition.addFieldInString("role_type", new String[] {"a_", "f_"});
        //         root.createChild(new EntityListPanelHandler(RawEntityListPanel.class, "acl_roles").setFilter(condition).setId("roles_cond").setTitle("ConditionTest"));
        //      }
        */

        root.getChildFactory().createChild("tabletest", "TableTest",
                new EntityListPanelHandler(RenderedEntityDataTablePanelTest.class, "settings"));

        {
            RelationalPath<?> entityPath = ApplicationSchema.instance.findRequiredEntity("settings")
                    .getQueryBuilder().getDefaultPath();
            Path<Comparable<?>> namePath = GenericTypeUtil
                    .unsafeCast(Expressions.path(String.class, entityPath, "name"));

            PopulatorColumnDescriptor column1 = new PopulatorColumnDescriptor("name", namePath,
                    new RowFieldPopulator<IEntityInstance>("name"));
            PopulatorColumnDescriptor column2 = new PopulatorColumnDescriptor("value",
                    new RowFieldPopulator<IEntityInstance>("data"));
            PopulatorColumnDescriptor[] columns = new PopulatorColumnDescriptor[] { column1, column2 };
            root.getChildFactory().createChild("tabletest2", "TableTest2",
                    new PopulatorBasedEntityListHandler("settings", columns));
        }

        root.getChildFactory().createChild("autoform-test", "Autoform",
                new PanelPageNavigationHandler(MyAutoformPanel.class, null, true, false));
        NavigationTabBarFactory.apply(root.findChildById("sub-one"));

    }

    /**
     *
     */
    @AutoformPropertyOrder({ "name1", "name2", "name3" })
    public static class MyAutoformBean implements Serializable {

        /**
         * the name1
         */
        private int name1;

        /**
         * the name2
         */
        private String name2;

        /**
         * the name3
         */
        private String name3;

        /**
         * Getter method for the name1.
         * @return the name1
         */
        //      @MyMaxLength(4)
        @MinIntegerValue(3)
        public int getName1() {
            return name1;
        }

        /**
         * Setter method for the name1.
         * @param name1 the name1 to set
         */
        public void setName1(final int name1) {
            this.name1 = name1;
        }

        /**
         * Getter method for the name2.
         * @return the name2
         */
        //      @AutoformValidator(MyValidator.class)
        public String getName2() {
            return name2;
        }

        /**
         * Setter method for the name2.
         * @param name2 the name2 to set
         */
        public void setName2(final String name2) {
            this.name2 = name2;
        }

        /**
         * Getter method for the name3.
         * @return the name3
         */
        public String getName3() {
            return name3;
        }

        /**
         * Setter method for the name3.
         * @param name3 the name3 to set
         */
        public void setName3(final String name3) {
            this.name3 = name3;
        }

    }

    /**
     *
     */
    public static class MyAutoformPanel extends AutoformPanel {

        /**
         * Constructor.
         * @param id the wicket id
         */
        public MyAutoformPanel(final String id) {
            super(id, new MyAutoformBean(), DefaultAutoformBeanDescriber.instance,
                    DefaultAutoformPropertyComponentFactory.instance);
        }

        /* (non-Javadoc)
         * @see name.martingeisse.wicket.autoform.AutoformPanel#onSuccessfulSubmit()
         */
        @Override
        protected void onSuccessfulSubmit() {
            System.out.println("*** SUBMIT ***");
        }

    }

    /**
     *
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @AutoformAssociatedValidator(MyValidator.class)
    public static @interface MyMaxLength {

        /**
         * @return the max length
         */
        public int value();

    }

}