This is an automated email from the ASF dual-hosted git repository. ntimofeev pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/master by this push: new 4d16b401c CAY-2785 Modeler: improve folder selection for cgen - better logic to select directory on new project save - update texteditor view on project save 4d16b401c is described below commit 4d16b401ca783e1063570fc998cb7e9af031b498 Author: Nikita Timofeev <stari...@gmail.com> AuthorDate: Tue Dec 6 17:46:30 2022 +0300 CAY-2785 Modeler: improve folder selection for cgen - better logic to select directory on new project save - update texteditor view on project save --- .../org/apache/cayenne/gen/internal/Utils.java | 71 ++++++++++++++++++++++ .../apache/cayenne/gen/xml/CgenSaverDelegate.java | 10 ++- .../editor/cgen/CodeGeneratorController.java | 30 ++++----- .../editor/cgen/domain/CgenTabController.java | 20 ------ .../apache/cayenne/modeler/util/ModelerUtil.java | 46 ++++---------- 5 files changed, 102 insertions(+), 75 deletions(-) diff --git a/cayenne-cgen/src/main/java/org/apache/cayenne/gen/internal/Utils.java b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/internal/Utils.java new file mode 100644 index 000000000..8901a1198 --- /dev/null +++ b/cayenne-cgen/src/main/java/org/apache/cayenne/gen/internal/Utils.java @@ -0,0 +1,71 @@ +/***************************************************************** + * 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 + * + * https://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.gen.internal; + +import java.io.File; +import java.util.Optional; + +/** + * Internally used utilities related to cgen. + * + * @since 5.0 + */ +public class Utils { + + /** + * @param path to check + * @return path in the maven src layout or {@code Optional.empty()} if we are not inside maven project structure + */ + public static Optional<String> getMavenSrcPathForPath(String path) { + // check if we are in src/test/resources + String testDirPath = checkDefaultMavenResourceDir(path, "test"); + if(testDirPath != null) { + return Optional.of(testDirPath); + } + + // check if we are in src/main/resources + String mainDirPath = checkDefaultMavenResourceDir(path, "main"); + if(mainDirPath != null) { + return Optional.of(mainDirPath); + } + + return Optional.empty(); + } + + private static String checkDefaultMavenResourceDir(String path, String dirType) { + 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(); + } +} 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 index faa35db29..a5d85fd14 100644 --- 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 @@ -22,6 +22,7 @@ import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.configuration.xml.DataChannelMetaData; import org.apache.cayenne.gen.CgenConfiguration; import org.apache.cayenne.gen.CgenConfigList; +import org.apache.cayenne.gen.internal.Utils; import org.apache.cayenne.map.DataMap; import org.apache.cayenne.project.extension.BaseSaverDelegate; @@ -70,16 +71,19 @@ public class CgenSaverDelegate extends BaseSaverDelegate { if(Files.isRegularFile(resourcePath)) { resourcePath = resourcePath.getParent(); } + Path oldRoot = cgenConfiguration.getRootPath(); if(oldRoot == null) { - cgenConfiguration.setRootPath(resourcePath); + Path cgenPath = Utils.getMavenSrcPathForPath(resourcePath.toString()) + .map(Path::of) + .orElse(resourcePath); + cgenConfiguration.setRootPath(cgenPath); } + Path prevPath = cgenConfiguration.buildPath(); if(prevPath != null) { if(prevPath.isAbsolute()) { - Path relPath = prevPath; - if (resourcePath.getRoot().equals(prevPath.getRoot())) { relPath = resourcePath.relativize(prevPath).normalize(); } 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 index d42650a69..7ab00e356 100644 --- 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 @@ -41,6 +41,7 @@ import org.apache.cayenne.modeler.ProjectController; import org.apache.cayenne.modeler.dialog.ErrorDebugDialog; import org.apache.cayenne.modeler.dialog.pref.GeneralPreferences; import org.apache.cayenne.modeler.editor.DbImportController; +import org.apache.cayenne.modeler.event.ProjectSavedEvent; import org.apache.cayenne.modeler.util.CayenneController; import org.apache.cayenne.modeler.util.ModelerUtil; import org.apache.cayenne.swing.BindingBuilder; @@ -49,8 +50,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.JOptionPane; -import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; @@ -150,6 +149,7 @@ public class CodeGeneratorController extends CayenneController implements ObjEnt projectController.addObjEntityListener(this); projectController.addEmbeddableListener(this); projectController.addDataMapListener(this); + projectController.addProjectSavedListener(this::onProjectSaved); } @Override @@ -311,23 +311,6 @@ public class CodeGeneratorController extends CayenneController implements ObjEnt map.getEmbeddables().forEach(embeddable -> configuration.loadEmbeddable(embeddable.getClassName())); Path basePath = Paths.get(ModelerUtil.initOutputFolder()); - - // TODO: this should be done in actual generation, not here - // no such folder - if (!Files.exists(basePath)) { - try { - Files.createDirectories(basePath); - } catch (IOException e) { - JOptionPane.showMessageDialog(getView(), "Can't create directory. Select a different one."); - return null; - } - } - // not a directory - if (!Files.isDirectory(basePath)) { - JOptionPane.showMessageDialog(this.getView(), basePath + " is not a valid directory."); - return null; - } - if (map.getLocation() != null) { configuration.setRootPath(basePath); } @@ -542,6 +525,15 @@ public class CodeGeneratorController extends CayenneController implements ObjEnt return cgenConfiguration; } + /** + * Update cgen path if project is saved and no path is already set manually + * @param e event we are processing + */ + public void onProjectSaved(ProjectSavedEvent e) { + // update path input + getStandardModeController().getView().getOutputFolder().setText(cgenConfiguration.getRootPath().toString()); + } + private final Predicate<ConfigurationNode> defaultPredicate = o -> o.acceptVisitor(new BaseConfigurationNodeVisitor<Boolean>() { @Override public Boolean visitDataMap(DataMap dataMap) { diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java index 324bb6b86..fd542b7bc 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/cgen/domain/CgenTabController.java @@ -19,9 +19,6 @@ package org.apache.cayenne.modeler.editor.cgen.domain; -import javax.swing.JOptionPane; -import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Set; @@ -93,23 +90,6 @@ public class CgenTabController extends GeneratorsTabController<CgenConfiguration CgenConfiguration cgenConfiguration = new CgenConfiguration(); cgenConfiguration.setDataMap(dataMap); Path basePath = Paths.get(ModelerUtil.initOutputFolder()); - - // no such folder - if (!Files.exists(basePath)) { - try { - Files.createDirectories(basePath); - } catch (IOException e) { - JOptionPane.showMessageDialog(getView(), "Can't create directory. Select a different one."); - return null; - } - } - - // not a directory - if (!Files.isDirectory(basePath)) { - JOptionPane.showMessageDialog(getView(), basePath + " is not a valid directory."); - return null; - } - cgenConfiguration.setRootPath(basePath); Preferences preferences = Application.getInstance().getPreferencesNode(GeneralPreferences.class, ""); if (preferences != null) { diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ModelerUtil.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ModelerUtil.java index 47c2c80f2..9b1c93b71 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ModelerUtil.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ModelerUtil.java @@ -44,6 +44,7 @@ import java.util.UUID; import org.apache.cayenne.configuration.DataChannelDescriptor; import org.apache.cayenne.configuration.DataNodeDescriptor; +import org.apache.cayenne.gen.internal.Utils; import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.modeler.Application; @@ -219,47 +220,26 @@ public final class ModelerUtil { child.setLocation(x, y); } + + /** + * Get default output path for the class generator. + * Current implementation of this method uses {@code cayenne.cgen.destdir} if set or tries to check + * if current project is inside Maven-like {@code resource} directory to return corresponding {@code src} directory. + * + * @return best guess for the cgen output * @since 4.1 */ public static String initOutputFolder() { - String path; if (System.getProperty("cayenne.cgen.destdir") != null) { return 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) { - return path; - } else { - File lastDir = lastPath.getExistingDirectory(false); - return lastDir != null ? lastDir.getAbsolutePath() : "."; - } } - } - private static 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(); + FSPath lastPath = Application.getInstance().getFrameController().getLastDirectory(); + return Utils.getMavenSrcPathForPath(lastPath.getPath()).orElseGet(() -> { + File lastDir = lastPath.getExistingDirectory(false); + return lastDir != null ? lastDir.getAbsolutePath() : "."; + }); } }