diff --git a/java.project.ui/apichanges.xml b/java.project.ui/apichanges.xml --- a/java.project.ui/apichanges.xml +++ b/java.project.ui/apichanges.xml @@ -107,6 +107,18 @@ + + + Allows to extend the New Java File Wizard by project specific panels + + + + + + Allows to extend the New Java File Wizard by project specific panels. + + + Desktop dependent Java Project Support UI extracted diff --git a/java.project.ui/manifest.mf b/java.project.ui/manifest.mf --- a/java.project.ui/manifest.mf +++ b/java.project.ui/manifest.mf @@ -3,7 +3,7 @@ OpenIDE-Module-Layer: org/netbeans/modules/java/project/ui/layer.xml OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/project/ui/Bundle.properties OpenIDE-Module-Needs: javax.script.ScriptEngine.freemarker -OpenIDE-Module-Specification-Version: 1.68 +OpenIDE-Module-Specification-Version: 1.69 OpenIDE-Module-Recommends: org.netbeans.spi.java.project.runner.JavaRunnerImplementation AutoUpdate-Show-In-Client: false diff --git a/java.project.ui/nbproject/project.properties b/java.project.ui/nbproject/project.properties --- a/java.project.ui/nbproject/project.properties +++ b/java.project.ui/nbproject/project.properties @@ -43,7 +43,7 @@ is.autoload=true javac.compilerargs=-Xlint -Xlint:-serial -javac.source=1.7 +javac.source=1.8 javadoc.overview=${basedir}/overview.html javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml @@ -63,4 +63,4 @@ **/JavadocAndSourceRootDetectionTest.class test.config.create.includes=\ - **/CreateProjectTest.class \ No newline at end of file + **/CreateProjectTest.class diff --git a/java.project.ui/src/org/netbeans/modules/java/project/ui/NewJavaFileWizardIterator.java b/java.project.ui/src/org/netbeans/modules/java/project/ui/NewJavaFileWizardIterator.java --- a/java.project.ui/src/org/netbeans/modules/java/project/ui/NewJavaFileWizardIterator.java +++ b/java.project.ui/src/org/netbeans/modules/java/project/ui/NewJavaFileWizardIterator.java @@ -52,6 +52,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -60,10 +61,13 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Optional; import java.util.Set; import javax.swing.JComponent; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.java.classpath.JavaClassPathConstants; import org.netbeans.api.java.project.JavaProjectConstants; @@ -90,6 +94,7 @@ import org.openide.loaders.DataObject; import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; +import org.netbeans.spi.java.project.support.ui.templates.JavaFileWizardIteratorFactory; /** * Wizard to create a new Java file. @@ -161,7 +166,9 @@ return new NewJavaFileWizardIterator(Type.MODULE_INFO); } - private WizardDescriptor.Panel[] createPanels (WizardDescriptor wizardDescriptor) { + private WizardDescriptor.Panel[] createPanels ( + @NonNull final WizardDescriptor wizardDescriptor, + @NonNull final Collection> itOut) { // Ask for Java folders Project project = Templates.getProject( wizardDescriptor ); @@ -178,18 +185,13 @@ }; } else { - + final List> panels = new ArrayList<>(); if (this.type == Type.FILE) { - return new WizardDescriptor.Panel[] { - JavaTemplates.createPackageChooser( project, groups ), - }; + panels.add(JavaTemplates.createPackageChooser( project, groups )); } else if (type == Type.PKG_INFO) { - return new WizardDescriptor.Panel[] { - new JavaTargetChooserPanel(project, groups, null, Type.PKG_INFO, true), - }; + panels.add(new JavaTargetChooserPanel(project, groups, null, Type.PKG_INFO, true)); } else if (type == Type.MODULE_INFO) { - List pnls = new ArrayList<>(); - pnls.add(new JavaTargetChooserPanel(project, groups, null, Type.MODULE_INFO, false)); + panels.add(new JavaTargetChooserPanel(project, groups, null, Type.MODULE_INFO, false)); Map> group2items = new HashMap<>(); for (SourceGroup group : groups) { try { @@ -211,9 +213,8 @@ } catch (Exception ex) {} } if (!group2items.isEmpty()) { - pnls.add(new MoveToModulePathPanel(group2items)); + panels.add(new MoveToModulePathPanel(group2items)); } - return pnls.toArray(new WizardDescriptor.Panel[pnls.size()]); } else { assert type == Type.PACKAGE; SourceGroup[] groovySourceGroups = sources.getSourceGroups(SOURCE_TYPE_GROOVY); @@ -232,12 +233,22 @@ all.addAll(Arrays.asList(resources)); groups = all.toArray(new SourceGroup[all.size()]); } - return new WizardDescriptor.Panel[] { - new JavaTargetChooserPanel(project, groups, null, Type.PACKAGE, false), - }; + panels.add(new JavaTargetChooserPanel(project, groups, null, Type.PACKAGE, false)); } + final JavaFileWizardIteratorFactory templateProvider = project.getLookup().lookup(JavaFileWizardIteratorFactory.class); + if (templateProvider != null) { + final WizardDescriptor.Iterator it = templateProvider.createIterator(Templates.getTemplate(wizardDescriptor )); + if (it != null) { + itOut.add(it); + panels.add(it.current()); + while(it.hasNext()) { + it.nextPanel(); + panels.add(it.current()); + } + } + } + return panels.toArray(new WizardDescriptor.Panel[panels.size()]); } - } private static SourceGroup[] checkNotNull (SourceGroup[] groups, Sources sources) { @@ -284,14 +295,24 @@ if (this.type == Type.PACKAGE) { targetName = targetName.replace( '.', '/' ); // NOI18N createdFile = FileUtil.createFolder( dir, targetName ); - } - else { + } else { DataObject dTemplate = DataObject.find( template ); DataObject dobj = dTemplate.createFromTemplate( df, targetName ); createdFile = dobj.getPrimaryFile(); } - - return Collections.singleton( createdFile ); + final Set res = new HashSet<>(); + res.add(createdFile); + asInstantiatingIterator(projectSpecificIterator) + .map((it)->{ + try { + return it.instantiate(); + } catch (IOException ioe) { + Exceptions.printStackTrace(ioe); + return null; + } + }) + .ifPresent(res::addAll); + return Collections.unmodifiableSet(res); } private void moveCPItems(Iterable cpItemsToMove, FileObject folder) { @@ -343,16 +364,32 @@ } catch (Exception ex) {} } } + + @NonNull + private static Optional> asInstantiatingIterator( + @NullAllowed final WizardDescriptor.Iterator it) { + return Optional.ofNullable(it) + .map((p)->{ + return p instanceof WizardDescriptor.InstantiatingIterator ? + (WizardDescriptor.InstantiatingIterator) p: + null; + }); + } private transient int index; private transient WizardDescriptor.Panel[] panels; private transient WizardDescriptor wiz; + private transient WizardDescriptor.Iterator projectSpecificIterator; @Override public void initialize(WizardDescriptor wiz) { this.wiz = wiz; index = 0; - panels = createPanels( wiz ); + final List> itOut = new ArrayList<>(1); + panels = createPanels(wiz, itOut); + projectSpecificIterator = itOut.get(0); + asInstantiatingIterator(projectSpecificIterator) + .ifPresent((it)->it.initialize(wiz)); // Make sure list of steps is accurate. String[] beforeSteps = null; Object prop = wiz.getProperty(WizardDescriptor.PROP_CONTENT_DATA); @@ -380,8 +417,11 @@ @Override public void uninitialize (WizardDescriptor wiz) { + asInstantiatingIterator(projectSpecificIterator) + .ifPresent((it)->it.uninitialize(wiz)); this.wiz = null; panels = null; + projectSpecificIterator = null; } @Override diff --git a/java.project.ui/src/org/netbeans/spi/java/project/support/ui/templates/JavaFileWizardIteratorFactory.java b/java.project.ui/src/org/netbeans/spi/java/project/support/ui/templates/JavaFileWizardIteratorFactory.java new file mode 100644 --- /dev/null +++ b/java.project.ui/src/org/netbeans/spi/java/project/support/ui/templates/JavaFileWizardIteratorFactory.java @@ -0,0 +1,70 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2016 Sun Microsystems, Inc. + */ +package org.netbeans.spi.java.project.support.ui.templates; + +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; +import org.openide.WizardDescriptor; +import org.openide.WizardDescriptor.Iterator; +import org.openide.filesystems.FileObject; + +/** + * Allows to extend the New Java File Wizard by project specific panels. + * The instance of the {@link JavaFileWizardIteratorFactory} placed in the + * project's Lookup is consulted by the New Java File Wizard for additional + * panels. + * @author Tomas Zezula + * @since 1.69 + */ +public interface JavaFileWizardIteratorFactory { + /** + * Creates an {@link Iterator} with project specific panels for given template. + * When the created {@link Iterator} is an instance of the {@link WizardDescriptor.InstantiatingIterator} + * the {@link WizardDescriptor.InstantiatingIterator} life cycle methods such as {@link WizardDescriptor.InstantiatingIterator#instantiate} + * are called on proper places. + * @param template the template to create additional panels for + * @return the {@link Iterator} with additional panels or null when no additional + * panels. + */ + @CheckForNull + Iterator createIterator(@NonNull FileObject template); +}