cgen. create ui
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/8119ffaa Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/8119ffaa Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/8119ffaa Branch: refs/heads/master Commit: 8119ffaa88f70787590df6b23bc86c031337b921 Parents: 831442c Author: Arseni Bulatski <ancars...@gmail.com> Authored: Thu Jun 14 16:57:22 2018 +0300 Committer: Arseni Bulatski <ancars...@gmail.com> Committed: Wed Oct 24 13:39:05 2018 +0300 ---------------------------------------------------------------------- .../cayenne/gen/xml/CgenConfigHandler.java | 23 + .../apache/cayenne/gen/xml/CgenExtension.java | 32 ++ .../cayenne/gen/xml/CgenLoaderDelegate.java | 28 + .../cayenne/gen/xml/CgenSaverDelegate.java | 20 + .../modeler/editor/DataMapTabbedView.java | 10 +- .../cayenne/modeler/editor/EditorView.java | 3 +- .../editor/cgen/ClassesTabController.java | 123 ++++ .../modeler/editor/cgen/ClassesTabPanel.java | 84 +++ .../editor/cgen/CodeGeneratorController.java | 146 +++++ .../cgen/CodeGeneratorControllerBase.java | 289 ++++++++++ .../modeler/editor/cgen/CodeGeneratorPane.java | 76 +++ .../editor/cgen/CustomModeController.java | 238 ++++++++ .../modeler/editor/cgen/CustomModePanel.java | 189 ++++++ .../editor/cgen/CustomPreferencesUpdater.java | 193 +++++++ .../editor/cgen/GeneratorController.java | 568 +++++++++++++++++++ .../editor/cgen/GeneratorControllerPanel.java | 53 ++ .../editor/cgen/GeneratorTabController.java | 71 +++ .../modeler/editor/cgen/GeneratorTabPanel.java | 33 ++ .../editor/cgen/StandardPanelComponent.java | 79 +++ .../modeler/init/CayenneModelerModule.java | 4 +- 20 files changed, 2256 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java ---------------------------------------------------------------------- diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java new file mode 100644 index 0000000..23f0ff3 --- /dev/null +++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenConfigHandler.java @@ -0,0 +1,23 @@ +package org.apache.cayenne.gen.xml; + +import org.apache.cayenne.configuration.xml.DataChannelMetaData; +import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler; +import org.apache.cayenne.dbsync.xml.DbImportExtension; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +public class CgenConfigHandler extends NamespaceAwareNestedTagHandler{ + + private DataChannelMetaData metaData; + + CgenConfigHandler(NamespaceAwareNestedTagHandler parentHandler, DataChannelMetaData metaData) { + super(parentHandler); + this.metaData = metaData; + this.targetNamespace = DbImportExtension.NAMESPACE; + } + + @Override + protected boolean processElement(String namespaceURI, String localName, Attributes attributes) throws SAXException { + return false; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java ---------------------------------------------------------------------- diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java new file mode 100644 index 0000000..619bffc --- /dev/null +++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenExtension.java @@ -0,0 +1,32 @@ +package org.apache.cayenne.gen.xml; + +import org.apache.cayenne.configuration.ConfigurationNodeVisitor; +import org.apache.cayenne.configuration.xml.DataChannelMetaData; +import org.apache.cayenne.di.Inject; +import org.apache.cayenne.project.Project; +import org.apache.cayenne.project.extension.LoaderDelegate; +import org.apache.cayenne.project.extension.ProjectExtension; +import org.apache.cayenne.project.extension.SaverDelegate; + +public class CgenExtension implements ProjectExtension { + + public static final String NAMESPACE = "http://cayenne.apache.org/schema/" + Project.VERSION + "/cgen"; + + @Inject + private DataChannelMetaData metaData; + + @Override + public LoaderDelegate createLoaderDelegate() { + return null; + } + + @Override + public SaverDelegate createSaverDelegate() { + return new CgenSaverDelegate(metaData); + } + + @Override + public ConfigurationNodeVisitor<String> createNamingDelegate() { + return null; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java ---------------------------------------------------------------------- diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java new file mode 100644 index 0000000..44438e3 --- /dev/null +++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenLoaderDelegate.java @@ -0,0 +1,28 @@ +package org.apache.cayenne.gen.xml; + +import org.apache.cayenne.configuration.xml.DataChannelMetaData; +import org.apache.cayenne.configuration.xml.NamespaceAwareNestedTagHandler; + +import org.apache.cayenne.project.extension.LoaderDelegate; + +public class CgenLoaderDelegate implements LoaderDelegate { + + private DataChannelMetaData metaData; + + CgenLoaderDelegate(DataChannelMetaData metaData){ + this.metaData = metaData; + } + + @Override + public String getTargetNamespace() { + return CgenExtension.NAMESPACE; + } + + @Override + public NamespaceAwareNestedTagHandler createHandler(NamespaceAwareNestedTagHandler parent, String tag) { +// if(CgenConfigHandler.CONFIG_TAG.equals(tag)) { +// return new CgenConfigHandler(parent, metaData); +// } + return null; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java ---------------------------------------------------------------------- diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java new file mode 100644 index 0000000..f9c7173 --- /dev/null +++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/xml/CgenSaverDelegate.java @@ -0,0 +1,20 @@ +package org.apache.cayenne.gen.xml; + +import org.apache.cayenne.configuration.xml.DataChannelMetaData; +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.project.extension.BaseSaverDelegate; + +public class CgenSaverDelegate extends BaseSaverDelegate{ + + private DataChannelMetaData metaData; + + CgenSaverDelegate(DataChannelMetaData metaData){ + this.metaData = metaData; + } + + @Override + public Void visitDataMap(DataMap dataMap) { + + return null; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java index ed1b6f1..bd9afc5 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapTabbedView.java @@ -18,12 +18,13 @@ ****************************************************************/ package org.apache.cayenne.modeler.editor; -import javax.swing.JScrollPane; -import javax.swing.JTabbedPane; - +import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; +import org.apache.cayenne.modeler.editor.cgen.CodeGeneratorController; import org.apache.cayenne.modeler.editor.dbimport.DbImportView; +import javax.swing.*; + /** * Data map editing tabs container @@ -55,8 +56,11 @@ public class DataMapTabbedView extends JTabbedPane { // must be wrapped in a scroll pane JScrollPane dataMapView = new JScrollPane(new DataMapView(mediator)); JScrollPane dbImportView = new JScrollPane(new DbImportView(mediator)); + CodeGeneratorController codeGeneratorController = new CodeGeneratorController(Application.getInstance().getFrameController(), mediator); + JScrollPane cgenView = new JScrollPane(codeGeneratorController.getView()); addTab("DataMap", dataMapView); addTab("DbImport", dbImportView); + addTab("Cgen", cgenView); } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java index e9b3290..5b4675a 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java @@ -103,7 +103,6 @@ public class EditorView extends JPanel implements ObjEntityDisplayListener, private SQLTemplateTabbedView sqlTemplateView; private EjbqlTabbedView ejbqlQueryView; private JTabbedPane dataNodeView; - protected ActionManager actionManager; private FilterController filterController; @@ -162,7 +161,7 @@ public class EditorView extends JPanel implements ObjEntityDisplayListener, public EditorView(ProjectController eventController) { this.eventController = eventController; - this.actionManager= eventController.getApplication().getActionManager(); + this.actionManager = eventController.getApplication().getActionManager(); initView(); initController(); http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java new file mode 100644 index 0000000..2b478ac --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabController.java @@ -0,0 +1,123 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.modeler.util.CayenneController; +import org.apache.cayenne.swing.BindingBuilder; +import org.apache.cayenne.swing.ImageRendererColumn; +import org.apache.cayenne.swing.ObjectBinding; +import org.apache.cayenne.swing.TableBindingBuilder; + +import javax.swing.*; +import java.awt.*; + +public class ClassesTabController extends CayenneController { + + public static final String GENERATE_PROPERTY = "generate"; + + protected ClassesTabPanel view; + protected ObjectBinding tableBinding; + + public ClassesTabController(CodeGeneratorControllerBase parent) { + super(parent); + + this.view = new ClassesTabPanel(); + } + + public void startup(DataMap dataMap){ + initBindings(); + } + + protected CodeGeneratorControllerBase getParentController() { + return (CodeGeneratorControllerBase) getParent(); + } + + public Component getView() { + return view; + } + + protected void initBindings() { + + BindingBuilder builder = new BindingBuilder( + getApplication().getBindingFactory(), + this); + + builder.bindToAction(view.getCheckAll(), "checkAllAction()"); + + TableBindingBuilder tableBuilder = new TableBindingBuilder(builder); + + tableBuilder.addColumn( + "", + "parent.setCurrentClass(#item), selected", + Boolean.class, + true, + Boolean.TRUE); + tableBuilder.addColumn( + "Class", + "parent.getItemName(#item)", + JLabel.class, + false, + "XXXXXXXXXXXXXX"); + + tableBuilder.addColumn( + "Comments, Warnings", + "parent.getProblem(#item)", + String.class, + false, + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + + this.tableBinding = tableBuilder.bindToTable(view.getTable(), "parent.classes"); + view.getTable().getColumnModel().getColumn(1).setCellRenderer(new ImageRendererColumn()); + } + + public boolean isSelected() { + return getParentController().isSelected(); + } + + public void setSelected(boolean selected) { + getParentController().setSelected(selected); + classSelectedAction(); + } + + /** + * A callback action that updates the state of Select All checkbox. + */ + public void classSelectedAction() { + int selectedCount = getParentController().getSelectedEntitiesSize() + getParentController().getSelectedEmbeddablesSize() ; + + if (selectedCount == 0) { + view.getCheckAll().setSelected(false); + } + else if (selectedCount == getParentController().getClasses().size()) { + view.getCheckAll().setSelected(true); + } + } + + /** + * An action that updates entity check boxes in response to the Select All state + * change. + */ + public void checkAllAction() { + if (getParentController().updateSelection(view.getCheckAll().isSelected() ? o -> true : o -> false)) { + tableBinding.updateView(); + } + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java new file mode 100644 index 0000000..e4fc20c --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/ClassesTabPanel.java @@ -0,0 +1,84 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + */ +public class ClassesTabPanel extends JPanel { + + protected JTable table; + protected JCheckBox checkAll; + protected JLabel checkAllLabel; + + public ClassesTabPanel() { + + this.table = new JTable(); + this.table.setRowHeight(22); + + // TODO: andrus 04/07/2006 - is there an easy way to stick that checkbox in the + // table header???? + this.checkAll = new JCheckBox(); + this.checkAllLabel = new JLabel("Check All Classes"); + + checkAll.addItemListener(new ItemListener() { + + public void itemStateChanged(ItemEvent event) { + if (checkAll.isSelected()) { + checkAllLabel.setText("Uncheck All Classess"); + } + else { + checkAllLabel.setText("Check All Classes"); + } + } + }); + + // assemble + JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING)); + topPanel.setBorder(UIManager.getBorder("ToolBar.border")); + topPanel.add(checkAll); + topPanel.add(checkAllLabel); + + JScrollPane tablePanel = new JScrollPane( + table, + ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + // set some minimal preferred size, so that it is smaller than other forms used in + // the dialog... this way we get the right automated overall size + tablePanel.setPreferredSize(new Dimension(300, 200)); + + setLayout(new BorderLayout()); + add(topPanel, BorderLayout.NORTH); + add(tablePanel, BorderLayout.CENTER); + } + + public JTable getTable() { + return table; + } + + public JCheckBox getCheckAll() { + return checkAll; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java new file mode 100644 index 0000000..8163acb --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorController.java @@ -0,0 +1,146 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import org.apache.cayenne.gen.ClassGenerationAction; +import org.apache.cayenne.modeler.ProjectController; +import org.apache.cayenne.modeler.dialog.ErrorDebugDialog; +import org.apache.cayenne.modeler.util.CayenneController; +import org.apache.cayenne.swing.BindingBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.*; +import java.awt.*; +import java.util.Collection; +import java.util.function.Predicate; + +/** + * A controller for the class generator dialog. + */ +public class CodeGeneratorController extends CodeGeneratorControllerBase { + /** + * Logger to print stack traces + */ + private static Logger logObj = LoggerFactory.getLogger(ErrorDebugDialog.class); + + protected CodeGeneratorPane view; + + protected ClassesTabController classesSelector; + protected GeneratorTabController generatorSelector; + + public CodeGeneratorController(CayenneController parent, ProjectController projectController) { + super(parent, projectController); + initListeners(); + this.classesSelector = new ClassesTabController(this); + this.generatorSelector = new GeneratorTabController(this); + view = new CodeGeneratorPane(generatorSelector.getView(), classesSelector.getView()); + initBindings(); + } + + private void initListeners(){ + projectController.addDataMapDisplayListener(e -> { + super.startup(e.getDataMap()); + classesSelector.startup(e.getDataMap()); + generatorSelector.startup(e.getDataMap()); + }); + } + + @Override + public Component getView() { + return view; + } + + protected void initBindings() { + BindingBuilder builder = new BindingBuilder( + getApplication().getBindingFactory(), + this); + + builder.bindToAction(view.getGenerateButton(), "generateAction()"); + builder.bindToAction(this, "classesSelectedAction()", SELECTED_PROPERTY); + builder.bindToAction(generatorSelector, "generatorSelectedAction()", + GeneratorTabController.GENERATOR_PROPERTY); + + generatorSelectedAction(); + } + + public void generatorSelectedAction() { + GeneratorController controller = generatorSelector.getGeneratorController(); + validate(controller); + + Predicate<Object> predicate = controller != null + ? controller.getDefaultClassFilter() + : o -> false; + + updateSelection(predicate); + classesSelector.classSelectedAction(); + } + + public void classesSelectedAction() { + int size = getSelectedEntitiesSize(); + String label; + + if (size == 0) { + label = "No entities selected"; + } + else if (size == 1) { + label = "One entity selected"; + } + else { + label = size + " entities selected"; + } + + label = label.concat("; "); + + int sizeEmb = getSelectedEmbeddablesSize(); + + if (sizeEmb == 0) { + label = label + "No embeddables selected"; + } + else if (sizeEmb == 1) { + label = label + "One embeddable selected"; + } + else { + label =label + sizeEmb + " embeddables selected"; + } + + view.getClassesCount().setText(label); + } + + public void generateAction() { + Collection<ClassGenerationAction> generators = generatorSelector.getGenerator(); + + if (generators != null) { + try { + for (ClassGenerationAction generator : generators) { + generator.execute(); + } + JOptionPane.showMessageDialog( + getView(), + "Class generation finished"); + } catch (Exception e) { + logObj.error("Error generating classes", e); + JOptionPane.showMessageDialog( + getView(), + "Error generating classes - " + e.getMessage()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java new file mode 100644 index 0000000..17196fa --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorControllerBase.java @@ -0,0 +1,289 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.map.Embeddable; +import org.apache.cayenne.map.ObjEntity; +import org.apache.cayenne.modeler.ProjectController; +import org.apache.cayenne.modeler.util.CayenneController; +import org.apache.cayenne.modeler.util.CellRenderers; +import org.apache.cayenne.validation.ValidationFailure; +import org.apache.cayenne.validation.ValidationResult; + +import javax.swing.*; +import java.awt.*; +import java.util.*; +import java.util.List; +import java.util.function.Predicate; + +/** + * A base superclass of a top controller for the code generator. Defines all common model + * parts used in class generation. + * + */ +public abstract class CodeGeneratorControllerBase extends CayenneController { + + public static final String SELECTED_PROPERTY = "selected"; + + protected Collection<DataMap> dataMaps; + + protected DataMap dataMap; + + protected ValidationResult validation; + + protected List<Object> classes; + + protected Set<String> selectedEntities; + protected Set<String> selectedEmbeddables; + + protected transient Object currentClass; + + protected ProjectController projectController; + + public CodeGeneratorControllerBase(CayenneController parent, ProjectController projectController) { + super(parent); + this.projectController = projectController; + this.classes = new ArrayList<>(); + + this.selectedEntities = new HashSet<>(); + this.selectedEmbeddables = new HashSet<>(); + } + + public void startup(DataMap dataMap){ + this.dataMap = dataMap; + classes.clear(); + this.classes.addAll(dataMap.getObjEntities()); + this.classes.addAll(dataMap.getEmbeddables()); + } + + public List<Object> getClasses() { + return classes; + } + + public abstract Component getView(); + + public void validate(GeneratorController validator) { + + ValidationResult validationBuffer = new ValidationResult(); + + if (validator != null) { + for (Object classObj : classes) { + if (classObj instanceof ObjEntity) { + validator.validateEntity( + validationBuffer, + (ObjEntity) classObj, + false); + } + else if (classObj instanceof Embeddable) { + validator.validateEmbeddable(validationBuffer, (Embeddable) classObj); + } + } + + } + + this.validation = validationBuffer; + } + + public boolean updateSelection(Predicate<Object> predicate) { + + boolean modified = false; + + for (Object classObj : classes) { + boolean select = predicate.test(classObj); + if (classObj instanceof ObjEntity) { + + if (select) { + if (selectedEntities.add(((ObjEntity) classObj).getName())) { + modified = true; + } + } + else { + if (selectedEntities.remove(((ObjEntity) classObj).getName())) { + modified = true; + } + } + } + else if (classObj instanceof Embeddable) { + if (select) { + if (selectedEmbeddables.add(((Embeddable) classObj).getClassName())) { + modified = true; + } + } + else { + if (selectedEmbeddables + .remove(((Embeddable) classObj).getClassName())) { + modified = true; + } + } + } + + } + + if (modified) { + firePropertyChange(SELECTED_PROPERTY, null, null); + } + + return modified; + } + + public List<Embeddable> getSelectedEmbeddables() { + + List<Embeddable> selected = new ArrayList<>(selectedEmbeddables.size()); + + for (Object classObj : classes) { + if (classObj instanceof Embeddable + && selectedEmbeddables.contains(((Embeddable) classObj) + .getClassName())) { + selected.add((Embeddable) classObj); + } + } + + return selected; + } + + public List<ObjEntity> getSelectedEntities() { + List<ObjEntity> selected = new ArrayList<>(selectedEntities.size()); + for (Object classObj : classes) { + if (classObj instanceof ObjEntity + && selectedEntities.contains(((ObjEntity) classObj).getName())) { + selected.add(((ObjEntity) classObj)); + } + } + + return selected; + } + + public int getSelectedEntitiesSize() { + return selectedEntities.size(); + } + + public int getSelectedEmbeddablesSize() { + return selectedEmbeddables.size(); + } + + /** + * Returns the first encountered validation problem for an antity matching the name or + * null if the entity is valid or the entity is not present. + */ + public String getProblem(Object obj) { + + String name = null; + + if (obj instanceof ObjEntity) { + name = ((ObjEntity) obj).getName(); + } + else if (obj instanceof Embeddable) { + name = ((Embeddable) obj).getClassName(); + } + + if (validation == null) { + return null; + } + + List failures = validation.getFailures(name); + if (failures.isEmpty()) { + return null; + } + + return ((ValidationFailure) failures.get(0)).getDescription(); + } + + public boolean isSelected() { + if (currentClass instanceof ObjEntity) { + return selectedEntities + .contains(((ObjEntity) currentClass).getName()); + } + if (currentClass instanceof Embeddable) { + return selectedEmbeddables + .contains(((Embeddable) currentClass).getClassName()); + } + return false; + + } + + public void setSelected(boolean selectedFlag) { + if (currentClass == null) { + return; + } + if (currentClass instanceof ObjEntity) { + if (selectedFlag) { + if (selectedEntities.add(((ObjEntity) currentClass).getName())) { + firePropertyChange(SELECTED_PROPERTY, null, null); + } + } + else { + if (selectedEntities.remove(((ObjEntity) currentClass).getName())) { + firePropertyChange(SELECTED_PROPERTY, null, null); + } + } + } + if (currentClass instanceof Embeddable) { + if (selectedFlag) { + if (selectedEmbeddables.add(((Embeddable) currentClass).getClassName())) { + firePropertyChange(SELECTED_PROPERTY, null, null); + } + } + else { + if (selectedEmbeddables + .remove(((Embeddable) currentClass).getClassName())) { + firePropertyChange(SELECTED_PROPERTY, null, null); + } + } + } + } + + public Object getCurrentClass() { + return currentClass; + } + + public void setCurrentClass(Object currentClass) { + this.currentClass = currentClass; + } + + public Collection<DataMap> getDataMaps() { + return dataMaps; + } + + public JLabel getItemName(Object obj) { + String className; + Icon icon; + if (obj instanceof Embeddable) { + className = ((Embeddable) obj).getClassName(); + icon = CellRenderers.iconForObject(new Embeddable()); + } else { + className = ((ObjEntity) obj).getName(); + icon = CellRenderers.iconForObject(new ObjEntity()); + } + JLabel labelIcon = new JLabel(); + labelIcon.setIcon(icon); + labelIcon.setVisible(true); + labelIcon.setText(className); + return labelIcon; + } + + public DataMap getDataMap() { + return dataMap; + } + + public ProjectController getProjectController() { + return projectController; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorPane.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorPane.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorPane.java new file mode 100644 index 0000000..334931a --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CodeGeneratorPane.java @@ -0,0 +1,76 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import org.apache.cayenne.swing.components.TopBorder; + +import javax.swing.*; +import java.awt.*; + +/** + */ +public class CodeGeneratorPane extends JSplitPane { + + protected JSplitPane splitPane; + + protected JButton generateButton; + protected JLabel classesCount; + + public CodeGeneratorPane(Component generatorPanel, Component entitySelectorPanel) { + super(); + + splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + + this.generateButton = new JButton("Generate"); + this.classesCount = new JLabel("No classes selected"); + classesCount.setFont(classesCount.getFont().deriveFont(10f)); + + JScrollPane scrollPane = new JScrollPane( + generatorPanel, + ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane.setPreferredSize(new Dimension(800, 400)); + + // assemble + splitPane.setRightComponent(scrollPane); + splitPane.setLeftComponent(entitySelectorPanel); + + JPanel messages = new JPanel(new BorderLayout()); + messages.add(classesCount, BorderLayout.WEST); + + JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttons.setBorder(TopBorder.create()); + buttons.add(classesCount); + buttons.add(Box.createHorizontalStrut(50)); + buttons.add(generateButton); + + setLayout(new BorderLayout()); + add(splitPane, BorderLayout.CENTER); + add(buttons, BorderLayout.SOUTH); + } + + public JButton getGenerateButton() { + return generateButton; + } + + public JLabel getClassesCount() { + return classesCount; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java new file mode 100644 index 0000000..8f4dac9 --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModeController.java @@ -0,0 +1,238 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import org.apache.cayenne.gen.ClassGenerationAction; +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.modeler.CodeTemplateManager; +import org.apache.cayenne.modeler.dialog.pref.PreferenceDialog; +import org.apache.cayenne.modeler.pref.DataMapDefaults; +import org.apache.cayenne.swing.BindingBuilder; +import org.apache.cayenne.swing.ObjectBinding; +import org.apache.cayenne.util.Util; + +import javax.swing.*; +import java.awt.*; +import java.util.*; +import java.util.List; + +/** + * A controller for the custom generation mode. + */ +public class CustomModeController extends GeneratorController { + + // correspond to non-public constants on MapClassGenerator. + static final String MODE_DATAMAP = "datamap"; + static final String MODE_ENTITY = "entity"; + static final String MODE_ALL = "all"; + + static final String DATA_MAP_MODE_LABEL = "DataMap generation"; + static final String ENTITY_MODE_LABEL = "Entity and Embeddable generation"; + static final String ALL_MODE_LABEL = "Generate all"; + + static final Map<String, String> modesByLabel = new HashMap<>(); + + static { + modesByLabel.put(DATA_MAP_MODE_LABEL, MODE_DATAMAP); + modesByLabel.put(ENTITY_MODE_LABEL, MODE_ENTITY); + modesByLabel.put(ALL_MODE_LABEL, MODE_ALL); + } + + protected CustomModePanel view; + protected CodeTemplateManager templateManager; + + protected ObjectBinding superTemplate; + protected ObjectBinding subTemplate; + + private BindingBuilder builder; + + private CustomPreferencesUpdater preferencesUpdater; + + public CustomPreferencesUpdater getCustomPreferencesUpdater() { + return preferencesUpdater; + } + + public CustomModeController(CodeGeneratorControllerBase parent) { + super(parent); + this.view = new CustomModePanel(); + bind(); + } + + private void bind() { + initBindings(new BindingBuilder(getApplication().getBindingFactory(), this)); + builder = new BindingBuilder(getApplication().getBindingFactory(), this); + builder.bindToAction(view.getManageTemplatesLink(), "popPreferencesAction()"); + + Object[] modeChoices = new Object[]{ENTITY_MODE_LABEL, DATA_MAP_MODE_LABEL, ALL_MODE_LABEL}; + view.getGenerationMode().setModel(new DefaultComboBoxModel(modeChoices)); + } + + public void startup(DataMap dataMap) { + super.startup(dataMap); + + // bind preferences and init defaults... + DataMapDefaults dataMapDefaults = getMapPreferences().get(getParentController().getDataMap()); + + if (Util.isEmptyString(dataMapDefaults.getSuperclassTemplate())) { + dataMapDefaults.setSuperclassTemplate(CodeTemplateManager.STANDARD_SERVER_SUPERCLASS); + } + + if (Util.isEmptyString(dataMapDefaults.getSubclassTemplate())) { + dataMapDefaults.setSubclassTemplate(CodeTemplateManager.STANDARD_SERVER_SUBCLASS); + } + + if (Util.isEmptyString(dataMapDefaults.getProperty("mode"))) { + dataMapDefaults.setProperty("mode", MODE_ENTITY); + } + + if (Util.isEmptyString(dataMapDefaults.getProperty("overwrite"))) { + dataMapDefaults.setBooleanProperty("overwrite", false); + } + + if (Util.isEmptyString(dataMapDefaults.getProperty("pairs"))) { + dataMapDefaults.setBooleanProperty("pairs", true); + } + + if (Util.isEmptyString(dataMapDefaults.getProperty("usePackagePath"))) { + dataMapDefaults.setBooleanProperty("usePackagePath", true); + } + + if (Util.isEmptyString(dataMapDefaults.getProperty("outputPattern"))) { + dataMapDefaults.setProperty("outputPattern", "*.java"); + } + + builder.bindToComboSelection(view.getGenerationMode(), "customPreferencesUpdater.mode").updateView(); + + builder.bindToStateChange(view.getOverwrite(), "customPreferencesUpdater.overwrite").updateView(); + + builder.bindToStateChange(view.getPairs(), "customPreferencesUpdater.pairs").updateView(); + + builder.bindToStateChange(view.getUsePackagePath(), "customPreferencesUpdater.usePackagePath").updateView(); + + subTemplate = builder.bindToComboSelection(view.getSubclassTemplate(), + "customPreferencesUpdater.subclassTemplate"); + + superTemplate = builder.bindToComboSelection(view.getSuperclassTemplate(), + "customPreferencesUpdater.superclassTemplate"); + + builder.bindToTextField(view.getOutputPattern(), "customPreferencesUpdater.outputPattern").updateView(); + + builder.bindToStateChange(view.getCreatePropertyNames(), "customPreferencesUpdater.createPropertyNames") + .updateView(); + + updateTemplates(); + } + + protected void createDefaults() { + TreeMap<DataMap, DataMapDefaults> map = new TreeMap<>(); + DataMap dataMap = getParentController().getDataMap(); + DataMapDefaults preferences; + preferences = getApplication().getFrameController().getProjectController() + .getDataMapPreferences(this.getClass().getName().replace(".", "/"), dataMap); + preferences.setSuperclassPackage(""); + preferences.updateSuperclassPackage(dataMap, false); + + map.put(dataMap, preferences); + + if (getOutputPath() == null) { + setOutputPath(preferences.getOutputPath()); + } + + setMapPreferences(map); + preferencesUpdater = new CustomPreferencesUpdater(map); + } + + protected GeneratorControllerPanel createView() { + if (getParentController().getDataMap() != view.getStandardPanelComponent().getDataMap()) { + DataMapDefaults dataMapDefaults = getMapPreferences().get(getParentController().getDataMap()); + view.getStandardPanelComponent().setDataMap(getParentController().getDataMap()); + view.getStandardPanelComponent().setPreferences(dataMapDefaults); + view.getStandardPanelComponent().getDataMapName().setText(view.getStandardPanelComponent().getDataMap().getName()); + BindingBuilder builder = new BindingBuilder(getApplication().getBindingFactory(), view.getStandardPanelComponent()); + builder.bindToTextField(view.getStandardPanelComponent().getSuperclassPackage(), "preferences.superclassPackage").updateView(); + } + return view; + } + + protected void updateTemplates() { + this.templateManager = getApplication().getCodeTemplateManager(); + + List<String> customTemplates = new ArrayList<>(templateManager.getCustomTemplates().keySet()); + Collections.sort(customTemplates); + + List<String> superTemplates = new ArrayList<>(templateManager.getStandardSuperclassTemplates()); + Collections.sort(superTemplates); + superTemplates.addAll(customTemplates); + + List<String> subTemplates = new ArrayList<>(templateManager.getStandardSubclassTemplates()); + Collections.sort(subTemplates); + subTemplates.addAll(customTemplates); + + this.view.getSubclassTemplate().setModel(new DefaultComboBoxModel(subTemplates.toArray())); + this.view.getSuperclassTemplate().setModel(new DefaultComboBoxModel(superTemplates.toArray())); + + superTemplate.updateView(); + subTemplate.updateView(); + } + + public Component getView() { + return view; + } + + public Collection<ClassGenerationAction> createGenerator() { + + mode = modesByLabel.get(view.getGenerationMode().getSelectedItem()).toString(); + + Collection<ClassGenerationAction> generators = super.createGenerator(); + + String superKey = view.getSuperclassTemplate().getSelectedItem().toString(); + String superTemplate = templateManager.getTemplatePath(superKey); + + String subKey = view.getSubclassTemplate().getSelectedItem().toString(); + String subTemplate = templateManager.getTemplatePath(subKey); + + for (ClassGenerationAction generator : generators) { + generator.setSuperTemplate(superTemplate); + generator.setTemplate(subTemplate); + generator.setOverwrite(view.getOverwrite().isSelected()); + generator.setUsePkgPath(view.getUsePackagePath().isSelected()); + generator.setMakePairs(view.getPairs().isSelected()); + generator.setCreatePropertyNames(view.getCreatePropertyNames().isSelected()); + + if (!Util.isEmptyString(view.getOutputPattern().getText())) { + generator.setOutputPattern(view.getOutputPattern().getText()); + } + } + + return generators; + } + + public void popPreferencesAction() { + new PreferenceDialog(getApplication().getFrameController()).startupAction(PreferenceDialog.TEMPLATES_KEY); + updateTemplates(); + } + + @Override + protected ClassGenerationAction newGenerator() { + ClassGenerationAction action = new ClassGenerationAction(); + getApplication().getInjector().injectMembers(action); + return action; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java new file mode 100644 index 0000000..538ff64 --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomModePanel.java @@ -0,0 +1,189 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import com.jgoodies.forms.builder.DefaultFormBuilder; +import com.jgoodies.forms.layout.FormLayout; +import org.apache.cayenne.swing.control.ActionLink; + +import javax.swing.*; +import java.awt.*; + +public class CustomModePanel extends GeneratorControllerPanel { + + protected JComboBox generationMode; + protected JComboBox subclassTemplate; + protected JComboBox superclassTemplate; + protected JCheckBox pairs; + protected JCheckBox overwrite; + protected JCheckBox usePackagePath; + protected JTextField outputPattern; + protected JCheckBox createPropertyNames; + + private JTextField additionalMaps; + private JButton selectAdditionalMaps; + private JCheckBox client; + private JTextField encoding; + private JComboBox embeddableTemplate; + private JComboBox embeddableSuperTemplate; + private JLabel dataMapName; + + private DefaultFormBuilder builder; + + protected ActionLink manageTemplatesLink; + + private StandardPanelComponent standardPanelComponent; + + public CustomModePanel() { + + this.generationMode = new JComboBox(); + this.superclassTemplate = new JComboBox(); + this.subclassTemplate = new JComboBox(); + this.pairs = new JCheckBox(); + this.overwrite = new JCheckBox(); + this.usePackagePath = new JCheckBox(); + this.outputPattern = new JTextField(); + this.createPropertyNames = new JCheckBox(); + this.manageTemplatesLink = new ActionLink("Customize Templates..."); + manageTemplatesLink.setFont(manageTemplatesLink.getFont().deriveFont(10f)); + + this.standardPanelComponent = new StandardPanelComponent(); + + this.additionalMaps = new JTextField(); + this.selectAdditionalMaps = new JButton("Select"); + this.client = new JCheckBox(); + this.encoding = new JTextField(); + this.embeddableTemplate = new JComboBox(); + this.embeddableSuperTemplate = new JComboBox(); + this.dataMapName = new JLabel(); + this.dataMapName.setFont(dataMapName.getFont().deriveFont(1)); + + pairs.addChangeListener(e -> { + superclassTemplate.setEnabled(pairs.isSelected()); + overwrite.setEnabled(!pairs.isSelected()); + }); + + // assemble + + FormLayout layout = new FormLayout( + "right:77dlu, 3dlu, fill:200:grow, 6dlu, fill:50dlu, 3dlu", ""); + builder = new DefaultFormBuilder(layout); + builder.setDefaultDialogBorder(); + + builder.append("Output Directory:", outputFolder, selectOutputFolder); + builder.nextLine(); + + builder.append("Additional DataMaps", additionalMaps, selectAdditionalMaps); + builder.nextLine(); + + builder.append("Generation Mode:", generationMode); + builder.nextLine(); + + builder.append("Subclass Template:", subclassTemplate); + builder.nextLine(); + + builder.append("Superclass Template:", superclassTemplate); + builder.nextLine(); + + builder.append("Embeddable Template", embeddableTemplate); + builder.nextLine(); + + builder.append("Embeddable Super Template", embeddableSuperTemplate); + builder.nextLine(); + + builder.append("Output Pattern:", outputPattern); + builder.nextLine(); + + builder.append("Encoding", encoding); + builder.nextLine(); + + builder.append("Make Pairs:", pairs); + builder.nextLine(); + + builder.append("Use Package Path:", usePackagePath); + builder.nextLine(); + + builder.append("Overwrite Subclasses:", overwrite); + builder.nextLine(); + + builder.append("Create Property Names:", createPropertyNames); + builder.nextLine(); + + builder.append("Client", client); + builder.nextLine(); + + builder.append(standardPanelComponent, 4); + + setLayout(new BorderLayout()); + add(builder.getPanel(), BorderLayout.CENTER); + + JPanel links = new JPanel(new FlowLayout(FlowLayout.TRAILING)); + links.add(manageTemplatesLink); + add(links, BorderLayout.SOUTH); + + add(builder.getPanel(), BorderLayout.CENTER); + } + + public void addDataMapLine(StandardPanelComponent dataMapLine) { + dataMapLines.add(dataMapLine); + builder.append(dataMapLine, 4); + builder.nextLine(); + } + + public JComboBox getGenerationMode() { + return generationMode; + } + + public ActionLink getManageTemplatesLink() { + return manageTemplatesLink; + } + + public JComboBox getSubclassTemplate() { + return subclassTemplate; + } + + public JComboBox getSuperclassTemplate() { + return superclassTemplate; + } + + public JCheckBox getOverwrite() { + return overwrite; + } + + public JCheckBox getPairs() { + return pairs; + } + + public JCheckBox getUsePackagePath() { + return usePackagePath; + } + + public JTextField getOutputPattern() { + return outputPattern; + } + + public JCheckBox getCreatePropertyNames() { + return createPropertyNames; + } + + public StandardPanelComponent getStandardPanelComponent() { + return standardPanelComponent; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomPreferencesUpdater.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomPreferencesUpdater.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomPreferencesUpdater.java new file mode 100644 index 0000000..469e594 --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/CustomPreferencesUpdater.java @@ -0,0 +1,193 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import org.apache.cayenne.map.DataMap; +import org.apache.cayenne.modeler.pref.DataMapDefaults; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +public class CustomPreferencesUpdater { + + enum Property { + SUBCLASS_TEMPLATE, + SUPERCLASS_TEMPLATE, + OVERWRITE, + PAIRS, + USE_PACKAGE_PATH, + MODE, + OUTPUT_PATTERN, + CREATE_PROPERTY_NAMES + } + + private static final String OVERWRITE = "overwrite"; + private static final String PAIRS = "pairs"; + private static final String USE_PACKAGE_PATH = "usePackagePath"; + private static final String MODE = "mode"; + private static final String OUTPUT_PATTERN = "outputPattern"; + private static final String CREATE_PROPERTY_NAMES = "createPropertyNames"; + + private Map<DataMap, DataMapDefaults> mapPreferences; + + + public CustomPreferencesUpdater(Map<DataMap, DataMapDefaults> mapPreferences) { + this.mapPreferences = mapPreferences; + } + + public String getMode() { + return (String) getProperty(Property.MODE); + } + + public void setMode(String mode) { + updatePreferences(Property.MODE, mode); + } + + public String getSubclassTemplate() { + return (String) getProperty(Property.SUBCLASS_TEMPLATE); + } + + public void setSubclassTemplate(String subclassTemplate) { + updatePreferences(Property.SUBCLASS_TEMPLATE, subclassTemplate); + } + + public String getSuperclassTemplate() { + return (String) getProperty(Property.SUPERCLASS_TEMPLATE); + } + + public void setSuperclassTemplate(String superclassTemplate) { + updatePreferences(Property.SUPERCLASS_TEMPLATE, superclassTemplate); + } + + public Boolean getOverwrite() { + return (Boolean) getProperty(Property.OVERWRITE); + } + + public void setOverwrite(Boolean overwrite) { + updatePreferences(Property.OVERWRITE, overwrite); + } + + public Boolean getPairs() { + return (Boolean) getProperty(Property.PAIRS); + } + + public void setPairs(Boolean pairs) { + updatePreferences(Property.PAIRS, pairs); + } + + public Boolean getUsePackagePath() { + return (Boolean) getProperty(Property.USE_PACKAGE_PATH); + } + + public void setUsePackagePath(Boolean usePackagePath) { + updatePreferences(Property.USE_PACKAGE_PATH, usePackagePath); + } + + public String getOutputPattern() { + return (String) getProperty(Property.OUTPUT_PATTERN); + } + + public void setOutputPattern(String outputPattern) { + updatePreferences(Property.OUTPUT_PATTERN, outputPattern); + } + + public Boolean getCreatePropertyNames() { + return (Boolean) getProperty(Property.CREATE_PROPERTY_NAMES); + } + + public void setCreatePropertyNames(Boolean createPropertyNames) { + updatePreferences(Property.CREATE_PROPERTY_NAMES, createPropertyNames); + } + + private Object getProperty(Property property) { + Object obj = null; + + Set<Entry<DataMap, DataMapDefaults>> entities = mapPreferences.entrySet(); + for (Entry<DataMap, DataMapDefaults> entry : entities) { + + switch (property) { + case MODE: + obj = entry.getValue().getProperty(MODE); + break; + case OUTPUT_PATTERN: + obj = entry.getValue().getProperty(OUTPUT_PATTERN); + break; + case SUBCLASS_TEMPLATE: + obj = entry.getValue().getSubclassTemplate(); + break; + case SUPERCLASS_TEMPLATE: + obj = entry.getValue().getSuperclassTemplate(); + break; + case OVERWRITE: + obj = entry.getValue().getBooleanProperty(OVERWRITE); + break; + case PAIRS: + obj = entry.getValue().getBooleanProperty(PAIRS); + break; + case USE_PACKAGE_PATH: + obj = entry.getValue().getBooleanProperty(USE_PACKAGE_PATH); + break; + case CREATE_PROPERTY_NAMES: + obj = entry.getValue().getBooleanProperty(CREATE_PROPERTY_NAMES); + break; + default: + throw new IllegalArgumentException("Bad type property: " + property); + } + + } + return obj; + } + + private void updatePreferences(Property property, Object value) { + Set<Entry<DataMap, DataMapDefaults>> entities = mapPreferences.entrySet(); + for (Entry<DataMap, DataMapDefaults> entry : entities) { + + switch (property) { + case MODE: + entry.getValue().setProperty(MODE, (String) value); + break; + case OUTPUT_PATTERN: + entry.getValue().setProperty(OUTPUT_PATTERN, (String) value); + break; + case SUBCLASS_TEMPLATE: + entry.getValue().setSubclassTemplate((String) value); + break; + case SUPERCLASS_TEMPLATE: + entry.getValue().setSuperclassTemplate((String) value); + break; + case OVERWRITE: + entry.getValue().setBooleanProperty(OVERWRITE, (Boolean) value); + break; + case PAIRS: + entry.getValue().setBooleanProperty(PAIRS, (Boolean) value); + break; + case USE_PACKAGE_PATH: + entry.getValue().setBooleanProperty(USE_PACKAGE_PATH, (Boolean) value); + break; + case CREATE_PROPERTY_NAMES: + entry.getValue().setBooleanProperty(CREATE_PROPERTY_NAMES, (Boolean) value); + break; + default: + throw new IllegalArgumentException("Bad type property: " + property); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java new file mode 100644 index 0000000..9370e3b --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorController.java @@ -0,0 +1,568 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import org.apache.cayenne.CayenneRuntimeException; +import org.apache.cayenne.gen.ArtifactsGenerationMode; +import org.apache.cayenne.gen.ClassGenerationAction; +import org.apache.cayenne.map.*; +import org.apache.cayenne.modeler.Application; +import org.apache.cayenne.modeler.dialog.pref.GeneralPreferences; +import org.apache.cayenne.modeler.pref.DataMapDefaults; +import org.apache.cayenne.modeler.pref.FSPath; +import org.apache.cayenne.modeler.util.CayenneController; +import org.apache.cayenne.modeler.util.CodeValidationUtil; +import org.apache.cayenne.swing.BindingBuilder; +import org.apache.cayenne.util.Util; +import org.apache.cayenne.validation.BeanValidationFailure; +import org.apache.cayenne.validation.SimpleValidationFailure; +import org.apache.cayenne.validation.ValidationFailure; +import org.apache.cayenne.validation.ValidationResult; + +import javax.swing.*; +import java.io.File; +import java.util.*; +import java.util.function.Predicate; +import java.util.prefs.Preferences; + +/** + * A mode-specific part of the code generation dialog. + * + */ +public abstract class GeneratorController extends CayenneController { + + protected String mode = ArtifactsGenerationMode.ALL.getLabel(); + protected Map<DataMap, DataMapDefaults> mapPreferences; + private String outputPath; + + public GeneratorController(CodeGeneratorControllerBase parent) { + super(parent); + } + + public void startup(DataMap dataMap){ + createDefaults(); + createView(); +// initBindings(new BindingBuilder(getApplication().getBindingFactory(), this)); + } + + public String getOutputPath() { + return outputPath; + } + + public void setOutputPath(String path) { + String old = this.outputPath; + this.outputPath = path; + if (this.outputPath != null && !this.outputPath.equals(old)) { + updatePreferences(path); + } + } + + public void updatePreferences(String path) { + if (mapPreferences == null) + return; + Set<DataMap> keys = mapPreferences.keySet(); + for (DataMap key : keys) { + mapPreferences + .get(key) + .setOutputPath(path); + } + } + + public void setMapPreferences(Map<DataMap, DataMapDefaults> mapPreferences) { + this.mapPreferences = mapPreferences; + } + + public Map<DataMap, DataMapDefaults> getMapPreferences() { + return this.mapPreferences; + } + + protected void initBindings(BindingBuilder bindingBuilder) { + + initOutputFolder(); + + JTextField outputFolder = ((GeneratorControllerPanel) getView()).getOutputFolder(); + JButton outputSelect = ((GeneratorControllerPanel) getView()).getSelectOutputFolder(); + + outputFolder.setText(getOutputPath()); + bindingBuilder.bindToAction(outputSelect, "selectOutputFolderAction()"); + bindingBuilder.bindToTextField(outputFolder, "outputPath"); + } + + protected CodeGeneratorControllerBase getParentController() { + return (CodeGeneratorControllerBase) getParent(); + } + + protected abstract GeneratorControllerPanel createView(); + + protected abstract void createDefaults(); + + /** + * Creates an appropriate subclass of {@link ClassGenerationAction}, + * returning it in an unconfigured state. Configuration is performed by + * {@link #createGenerator()} method. + */ + protected abstract ClassGenerationAction newGenerator(); + + /** + * Creates a class generator for provided selections. + */ + public Collection<ClassGenerationAction> createGenerator() { + + File outputDir = getOutputDir(); + + // no destination folder + if (outputDir == null) { + JOptionPane.showMessageDialog(this.getView(), "Select directory for source files."); + return null; + } + + // no such folder + if (!outputDir.exists() && !outputDir.mkdirs()) { + JOptionPane.showMessageDialog(this.getView(), "Can't create directory " + outputDir + + ". Select a different one."); + return null; + } + + // not a directory + if (!outputDir.isDirectory()) { + JOptionPane.showMessageDialog(this.getView(), outputDir + " is not a valid directory."); + return null; + } + + // remove generic entities... + Collection<ObjEntity> selectedEntities = new ArrayList<>(getParentController().getSelectedEntities()); + selectedEntities.removeIf(ObjEntity::isGeneric); + + Collection<ClassGenerationAction> generators = new ArrayList<>(); + Collection<StandardPanelComponent> dataMapLines = ((GeneratorControllerPanel) getView()).getDataMapLines(); + DataMap map = getParentController().getDataMap(); + try { + ClassGenerationAction generator = newGenerator(); + generator.setArtifactsGenerationMode(mode); + generator.setDataMap(map); + + LinkedList<ObjEntity> objEntities = new LinkedList<>(map.getObjEntities()); + objEntities.retainAll(selectedEntities); + generator.addEntities(objEntities); + + LinkedList<Embeddable> embeddables = new LinkedList<>(map.getEmbeddables()); + embeddables.retainAll(getParentController().getSelectedEmbeddables()); + generator.addEmbeddables(embeddables); + + generator.addQueries(map.getQueryDescriptors()); + + Preferences preferences = application.getPreferencesNode(GeneralPreferences.class, ""); + + if (preferences != null) { + generator.setEncoding(preferences.get(GeneralPreferences.ENCODING_PREFERENCE, null)); + } + + generator.setDestDir(outputDir); + generator.setMakePairs(true); + generator.setForce(true); + + for (StandardPanelComponent dataMapLine : dataMapLines) { + if (dataMapLine.getDataMap() == map && !Util.isEmptyString(dataMapLine.getSuperclassPackage().getText())) { + generator.setSuperPkg(dataMapLine.getSuperclassPackage().getText()); + break; + } + } + + generators.add(generator); + } catch (CayenneRuntimeException exception) { + JOptionPane.showMessageDialog(this.getView(), exception.getUnlabeledMessage()); + return null; + } + + + return generators; + } + + public void validateEmbeddable(ValidationResult validationBuffer, Embeddable embeddable) { + ValidationFailure embeddableFailure = validateEmbeddable(embeddable); + if (embeddableFailure != null) { + validationBuffer.addFailure(embeddableFailure); + return; + } + + for (EmbeddableAttribute attribute : embeddable.getAttributes()) { + ValidationFailure failure = validateEmbeddableAttribute(attribute); + if (failure != null) { + validationBuffer.addFailure(failure); + return; + } + } + } + + private ValidationFailure validateEmbeddableAttribute(EmbeddableAttribute attribute) { + String name = attribute.getEmbeddable().getClassName(); + + ValidationFailure emptyName = BeanValidationFailure.validateNotEmpty(name, "attribute.name", + attribute.getName()); + if (emptyName != null) { + return emptyName; + } + + ValidationFailure badName = CodeValidationUtil.validateJavaIdentifier(name, "attribute.name", + attribute.getName()); + if (badName != null) { + return badName; + } + + ValidationFailure emptyType = BeanValidationFailure.validateNotEmpty(name, "attribute.type", + attribute.getType()); + if (emptyType != null) { + return emptyType; + } + + ValidationFailure badType = BeanValidationFailure.validateJavaClassName(name, "attribute.type", + attribute.getType()); + if (badType != null) { + return badType; + } + + return null; + } + + protected ValidationFailure validateEmbeddable(Embeddable embeddable) { + + String name = embeddable.getClassName(); + + ValidationFailure emptyClass = BeanValidationFailure.validateNotEmpty(name, "className", + embeddable.getClassName()); + if (emptyClass != null) { + return emptyClass; + } + + ValidationFailure badClass = BeanValidationFailure.validateJavaClassName(name, "className", + embeddable.getClassName()); + if (badClass != null) { + return badClass; + } + + return null; + } + + public void validateEntity(ValidationResult validationBuffer, ObjEntity entity, boolean clientValidation) { + + ValidationFailure entityFailure = validateEntity(clientValidation ? entity.getClientEntity() : entity); + if (entityFailure != null) { + validationBuffer.addFailure(entityFailure); + return; + } + + for (ObjAttribute attribute : entity.getAttributes()) { + if (attribute instanceof EmbeddedAttribute) { + EmbeddedAttribute embeddedAttribute = (EmbeddedAttribute) attribute; + for (ObjAttribute subAttribute : embeddedAttribute.getAttributes()) { + ValidationFailure failure = validateEmbeddedAttribute(subAttribute); + if (failure != null) { + validationBuffer.addFailure(failure); + return; + } + } + } else { + + ValidationFailure failure = validateAttribute(attribute); + if (failure != null) { + validationBuffer.addFailure(failure); + return; + } + } + } + + for (ObjRelationship rel : entity.getRelationships()) { + ValidationFailure failure = validateRelationship(rel, clientValidation); + if (failure != null) { + validationBuffer.addFailure(failure); + return; + } + } + } + + protected ValidationFailure validateEntity(ObjEntity entity) { + + String name = entity.getName(); + + if (entity.isGeneric()) { + return new SimpleValidationFailure(name, "Generic class"); + } + + ValidationFailure emptyClass = BeanValidationFailure.validateNotEmpty(name, "className", entity.getClassName()); + if (emptyClass != null) { + return emptyClass; + } + + ValidationFailure badClass = BeanValidationFailure.validateJavaClassName(name, "className", + entity.getClassName()); + if (badClass != null) { + return badClass; + } + + if (entity.getSuperClassName() != null) { + ValidationFailure badSuperClass = BeanValidationFailure.validateJavaClassName(name, "superClassName", + entity.getSuperClassName()); + if (badSuperClass != null) { + return badSuperClass; + } + } + + return null; + } + + protected ValidationFailure validateAttribute(ObjAttribute attribute) { + + String name = attribute.getEntity().getName(); + + ValidationFailure emptyName = BeanValidationFailure.validateNotEmpty(name, "attribute.name", + attribute.getName()); + if (emptyName != null) { + return emptyName; + } + + ValidationFailure badName = CodeValidationUtil.validateJavaIdentifier(name, "attribute.name", + attribute.getName()); + if (badName != null) { + return badName; + } + + ValidationFailure emptyType = BeanValidationFailure.validateNotEmpty(name, "attribute.type", + attribute.getType()); + if (emptyType != null) { + return emptyType; + } + + ValidationFailure badType = BeanValidationFailure.validateJavaClassName(name, "attribute.type", + attribute.getType()); + if (badType != null) { + return badType; + } + + return null; + } + + protected ValidationFailure validateEmbeddedAttribute(ObjAttribute attribute) { + + String name = attribute.getEntity().getName(); + + // validate embeddedAttribute and attribute names + // embeddedAttribute returned attibute as + // [name_embeddedAttribute].[name_attribute] + String[] attributes = attribute.getName().split("\\."); + String nameEmbeddedAttribute = attributes[0]; + int beginIndex = attributes[0].length(); + String attr = attribute.getName().substring(beginIndex + 1); + + ValidationFailure emptyEmbeddedName = BeanValidationFailure.validateNotEmpty(name, "attribute.name", + nameEmbeddedAttribute); + if (emptyEmbeddedName != null) { + return emptyEmbeddedName; + } + + ValidationFailure badEmbeddedName = CodeValidationUtil.validateJavaIdentifier(name, "attribute.name", + nameEmbeddedAttribute); + if (badEmbeddedName != null) { + return badEmbeddedName; + } + + ValidationFailure emptyName = BeanValidationFailure.validateNotEmpty(name, "attribute.name", attr); + if (emptyName != null) { + return emptyName; + } + + ValidationFailure badName = CodeValidationUtil.validateJavaIdentifier(name, "attribute.name", attr); + if (badName != null) { + return badName; + } + + ValidationFailure emptyType = BeanValidationFailure.validateNotEmpty(name, "attribute.type", + attribute.getType()); + if (emptyType != null) { + return emptyType; + } + + ValidationFailure badType = BeanValidationFailure.validateJavaClassName(name, "attribute.type", + attribute.getType()); + if (badType != null) { + return badType; + } + + return null; + } + + protected ValidationFailure validateRelationship(ObjRelationship relationship, boolean clientValidation) { + + String name = relationship.getSourceEntity().getName(); + + ValidationFailure emptyName = BeanValidationFailure.validateNotEmpty(name, "relationship.name", + relationship.getName()); + if (emptyName != null) { + return emptyName; + } + + ValidationFailure badName = CodeValidationUtil.validateJavaIdentifier(name, "relationship.name", + relationship.getName()); + if (badName != null) { + return badName; + } + + if (!relationship.isToMany()) { + + ObjEntity targetEntity = relationship.getTargetEntity(); + + if (clientValidation && targetEntity != null) { + targetEntity = targetEntity.getClientEntity(); + } + + if (targetEntity == null) { + + return new BeanValidationFailure(name, "relationship.targetEntity", "No target entity"); + } else if (!targetEntity.isGeneric()) { + ValidationFailure emptyClass = BeanValidationFailure.validateNotEmpty(name, + "relationship.targetEntity.className", targetEntity.getClassName()); + if (emptyClass != null) { + return emptyClass; + } + + ValidationFailure badClass = BeanValidationFailure.validateJavaClassName(name, + "relationship.targetEntity.className", targetEntity.getClassName()); + if (badClass != null) { + return badClass; + } + } + } + + return null; + } + + /** + * Returns a predicate for default entity selection in a given mode. + */ + public Predicate getDefaultClassFilter() { + final ObjEntity selectedEntity = Application.getInstance().getFrameController().getProjectController() + .getCurrentObjEntity(); + + final Embeddable selectedEmbeddable = Application.getInstance().getFrameController().getProjectController() + .getCurrentEmbeddable(); + + if (selectedEntity != null) { + // select a single entity + final boolean hasProblem = getParentController().getProblem(selectedEntity.getName()) != null; + return object -> !hasProblem && object == selectedEntity; + } else if (selectedEmbeddable != null) { + // select a single embeddable + final boolean hasProblem = getParentController().getProblem(selectedEmbeddable.getClassName()) != null; + return object -> !hasProblem && object == selectedEmbeddable; + } else { + // select all entities + return object -> { + if (object instanceof ObjEntity) { + return getParentController().getProblem(((ObjEntity) object).getName()) == null; + } + + if (object instanceof Embeddable) { + return getParentController().getProblem(((Embeddable) object).getClassName()) == null; + } + + return false; + }; + } + } + + public File getOutputDir() { + String dir = ((GeneratorControllerPanel) getView()).getOutputFolder().getText(); + return dir != null ? new File(dir) : new File(System.getProperty("user.dir")); + } + + /** + * An action method that pops up a file chooser dialog to pick the + * generation directory. + */ + public void selectOutputFolderAction() { + + JTextField outputFolder = ((GeneratorControllerPanel) getView()).getOutputFolder(); + + String currentDir = outputFolder.getText(); + + JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setDialogType(JFileChooser.OPEN_DIALOG); + + // guess start directory + if (!Util.isEmptyString(currentDir)) { + chooser.setCurrentDirectory(new File(currentDir)); + } else { + FSPath lastDir = Application.getInstance().getFrameController().getLastDirectory(); + lastDir.updateChooser(chooser); + } + + int result = chooser.showOpenDialog(getView()); + if (result == JFileChooser.APPROVE_OPTION) { + File selected = chooser.getSelectedFile(); + + // update model + String path = selected.getAbsolutePath(); + outputFolder.setText(path); + setOutputPath(path); + } + } + + private void initOutputFolder() { + String path; + if (getOutputPath() == null) { + if (System.getProperty("cayenne.cgen.destdir") != null) { + setOutputPath(System.getProperty("cayenne.cgen.destdir")); + } else { + // init default directory.. + FSPath lastPath = Application.getInstance().getFrameController().getLastDirectory(); + + path = checkDefaultMavenResourceDir(lastPath, "test"); + + if (path != null || (path = checkDefaultMavenResourceDir(lastPath, "main")) != null) { + setOutputPath(path); + } else { + File lastDir = (lastPath != null) ? lastPath.getExistingDirectory(false) : null; + setOutputPath(lastDir != null ? lastDir.getAbsolutePath() : null); + } + } + } + } + + private String checkDefaultMavenResourceDir(FSPath lastPath, String dirType) { + String path = lastPath.getPath(); + String resourcePath = buildFilePath("src", dirType, "resources"); + int idx = path.indexOf(resourcePath); + if (idx < 0) { + return null; + } + return path.substring(0, idx) + buildFilePath("src", dirType, "java"); + } + + private static String buildFilePath(String... pathElements) { + if (pathElements.length == 0) { + return ""; + } + StringBuilder path = new StringBuilder(pathElements[0]); + for (int i = 1; i < pathElements.length; i++) { + path.append(File.separator).append(pathElements[i]); + } + return path.toString(); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/8119ffaa/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java ---------------------------------------------------------------------- diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java new file mode 100644 index 0000000..9b836bd --- /dev/null +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/GeneratorControllerPanel.java @@ -0,0 +1,53 @@ +/***************************************************************** + * 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.cayenne.modeler.editor.cgen; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Collection; + +/** + * A generic panel that is a superclass of generator panels, defining common fields. + * + */ +public class GeneratorControllerPanel extends JPanel { + + protected Collection<StandardPanelComponent> dataMapLines; + protected JTextField outputFolder; + protected JButton selectOutputFolder; + + public GeneratorControllerPanel() { + this.dataMapLines = new ArrayList<>(); + this.outputFolder = new JTextField(); + this.selectOutputFolder = new JButton("Select"); + } + + public JTextField getOutputFolder() { + return outputFolder; + } + + public JButton getSelectOutputFolder() { + return selectOutputFolder; + } + + public Collection<StandardPanelComponent> getDataMapLines() { + return dataMapLines; + } +}