/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
*
* 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
* Microsystems, Inc. All Rights Reserved.
*
* 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.
*/
package org.netbeans.modules.scala.project.ui.customizer;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Vector;
import javax.swing.ButtonModel;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JToggleButton;
import javax.swing.ListCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import org.netbeans.api.queries.FileEncodingQuery;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.ant.AntBuildExtender;
import org.netbeans.modules.java.api.common.SourceRoots;
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
import org.netbeans.modules.java.api.common.classpath.ClassPathSupport;
import org.netbeans.modules.java.api.common.project.ProjectProperties;
import org.netbeans.modules.java.api.common.project.ui.ClassPathUiSupport;
import org.netbeans.modules.java.api.common.project.ui.customizer.ClassPathListCellRenderer;
import org.netbeans.modules.java.api.common.project.ui.customizer.SourceRootsUi;
import org.netbeans.modules.java.api.common.ui.PlatformUiSupport;
import org.netbeans.modules.java.api.common.util.CommonProjectUtils;
import org.netbeans.modules.scala.project.J2SEProject;
import org.netbeans.modules.scala.project.J2SEProjectType;
import org.netbeans.modules.scala.project.J2SEProjectUtil;
import org.netbeans.spi.java.project.support.ui.IncludeExcludeVisualizer;
import org.netbeans.spi.java.project.support.ui.SharableLibrariesUtils;
import org.netbeans.spi.project.ActionProvider;
import org.netbeans.spi.project.support.ant.AntProjectHelper;
import org.netbeans.spi.project.support.ant.EditableProperties;
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
import org.netbeans.spi.project.support.ant.ReferenceHelper;
import org.netbeans.spi.project.support.ant.ui.StoreGroup;
import org.openide.ErrorManager;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.Mutex;
import org.openide.util.MutexException;
import org.openide.util.Utilities;
import org.openide.util.lookup.Lookups;
/**
* @author Petr Hrebejk
*/
public class J2SEProjectProperties {
//Hotfix of the issue #70058
//Should be removed when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
private static final Integer BOOLEAN_KIND_TF = new Integer( 0 );
private static final Integer BOOLEAN_KIND_YN = new Integer( 1 );
private static final Integer BOOLEAN_KIND_ED = new Integer( 2 );
private static final String COS_MARK = ".netbeans_automatic_build"; //NOI18N
private Integer javacDebugBooleanKind;
private Integer doJarBooleanKind;
private Integer javadocPreviewBooleanKind;
// Special properties of the project
public static final String J2SE_PROJECT_NAME = "j2se.project.name"; // NOI18N
public static final String JAVA_PLATFORM = "platform.active"; // NOI18N
// folowing properties have moved to ProjectProperties in java.api.common module:
//public static final String JAVAC_CLASSPATH = "javac.classpath"; // NOI18N
//public static final String RUN_CLASSPATH = "run.classpath"; // NOI18N
//public static final String JAVAC_TEST_CLASSPATH = "javac.test.classpath"; // NOI18N
//public static final String RUN_TEST_CLASSPATH = "run.test.classpath"; // NOI18N
//public static final String BUILD_CLASSES_DIR = "build.classes.dir"; // NOI18N
//public static final String BUILD_TEST_CLASSES_DIR = "build.test.classes.dir"; // NOI18N
//public static final String INCLUDES = "includes"; // NOI18N
//public static final String EXCLUDES = "excludes"; // NOI18N
//public static final String[] WELL_KNOWN_PATHS = new String[] {
//public static final String ANT_ARTIFACT_PREFIX = "${reference."; // NOI18N
// Properties stored in the PROJECT.PROPERTIES
public static final String DIST_DIR = "dist.dir"; // NOI18N
public static final String DIST_JAR = "dist.jar"; // NOI18N
public static final String RUN_JVM_ARGS = "run.jvmargs"; // NOI18N
public static final String RUN_WORK_DIR = "work.dir"; // NOI18N
public static final String DEBUG_CLASSPATH = "debug.classpath"; // NOI18N
public static final String JAR_COMPRESS = "jar.compress"; // NOI18N
public static final String MAIN_CLASS = "main.class"; // NOI18N
public static final String JAVAC_SOURCE = "javac.source"; // NOI18N
public static final String JAVAC_TARGET = "javac.target"; // NOI18N
public static final String JAVAC_DEBUG = "javac.debug"; // NOI18N
public static final String JAVAC_DEPRECATION = "javac.deprecation"; // NOI18N
public static final String SCALAC_DEPRECATION = "scalac.deprecation"; // NOI18N
public static final String SCALAC_UNCHECKED = "scalac.unchecked"; // NOI18N
public static final String JAVAC_COMPILER_ARG = "javac.compilerargs"; //NOI18N
public static final String SCALAC_COMPILER_ARG = "scalac.compilerargs"; //NOI18N
public static final String BUILD_DIR = "build.dir"; // NOI18N
public static final String BUILD_TEST_RESULTS_DIR = "build.test.results.dir"; // NOI18N
public static final String BUILD_CLASSES_EXCLUDES = "build.classes.excludes"; // NOI18N
public static final String DIST_JAVADOC_DIR = "dist.javadoc.dir"; // NOI18N
public static final String NO_DEPENDENCIES="no.dependencies"; // NOI18N
public static final String DEBUG_TEST_CLASSPATH = "debug.test.classpath"; // NOI18N
public static final String SOURCE_ENCODING="source.encoding"; // NOI18N
/** @since org.netbeans.modules.java.j2seproject/1 1.12 */
public static final String DO_DEPEND = "do.depend"; // NOI18N
/** @since org.netbeans.modules.java.j2seproject/1 1.12 */
public static final String DO_JAR = "do.jar"; // NOI18N
/** @since org.netbeans.modules.java.j2seproject/1 1.21 */
public static final String COMPILE_ON_SAVE = "compile.on.save"; // NOI18N
/** @since org.netbeans.modules.java.j2seproject/1 1.19 */
public static final String COMPILE_ON_SAVE_UNSUPPORTED_PREFIX = "compile.on.save.unsupported"; // NOI18N
public static final String SYSTEM_PROPERTIES_RUN_PREFIX = "run-sys-prop."; // NOI18N
public static final String SYSTEM_PROPERTIES_TEST_PREFIX = "test-sys-prop."; // NOI18N
public static final String JAVADOC_PRIVATE="javadoc.private"; // NOI18N
public static final String JAVADOC_NO_TREE="javadoc.notree"; // NOI18N
public static final String JAVADOC_USE="javadoc.use"; // NOI18N
public static final String JAVADOC_NO_NAVBAR="javadoc.nonavbar"; // NOI18N
public static final String JAVADOC_NO_INDEX="javadoc.noindex"; // NOI18N
public static final String JAVADOC_SPLIT_INDEX="javadoc.splitindex"; // NOI18N
public static final String JAVADOC_AUTHOR="javadoc.author"; // NOI18N
public static final String JAVADOC_VERSION="javadoc.version"; // NOI18N
public static final String JAVADOC_WINDOW_TITLE="javadoc.windowtitle"; // NOI18N
public static final String JAVADOC_ENCODING="javadoc.encoding"; // NOI18N
public static final String JAVADOC_ADDITIONALPARAM="javadoc.additionalparam"; // NOI18N
public static final String APPLICATION_TITLE ="application.title"; // NOI18N
public static final String APPLICATION_VENDOR ="application.vendor"; // NOI18N
public static final String APPLICATION_DESC ="application.desc"; // NOI18N
public static final String APPLICATION_HOMEPAGE ="application.homepage"; // NOI18N
public static final String APPLICATION_SPLASH ="application.splash"; // NOI18N
// Properties stored in the PRIVATE.PROPERTIES
public static final String APPLICATION_ARGS = "application.args"; // NOI18N
public static final String JAVADOC_PREVIEW="javadoc.preview"; // NOI18N
// Main build.xml location
public static final String BUILD_SCRIPT ="buildfile"; //NOI18N
//NB 6.1 tracking of files modifications
public static final String TRACK_FILE_CHANGES="track.file.changes"; //NOI18N
ClassPathSupport cs;
// SOURCE ROOTS
// public static final String SOURCE_ROOTS = "__virtual_source_roots__"; //NOI18N
// public static final String TEST_ROOTS = "__virtual_test_roots__"; // NOI18N
// MODELS FOR VISUAL CONTROLS
// CustomizerSources
DefaultTableModel SOURCE_ROOTS_MODEL;
DefaultTableModel TEST_ROOTS_MODEL;
ComboBoxModel JAVAC_SOURCE_MODEL;
// CustomizerLibraries
DefaultListModel JAVAC_CLASSPATH_MODEL;
DefaultListModel JAVAC_TEST_CLASSPATH_MODEL;
DefaultListModel RUN_CLASSPATH_MODEL;
DefaultListModel RUN_TEST_CLASSPATH_MODEL;
ComboBoxModel PLATFORM_MODEL;
ListCellRenderer CLASS_PATH_LIST_RENDERER;
ListCellRenderer PLATFORM_LIST_RENDERER;
ListCellRenderer JAVAC_SOURCE_RENDERER;
Document SHARED_LIBRARIES_MODEL;
// CustomizerCompile
ButtonModel JAVAC_DEPRECATION_MODEL;
ButtonModel SCALAC_DEPRECATION_MODEL;
ButtonModel SCALAC_UNCHECKED_MODEL;
ButtonModel JAVAC_DEBUG_MODEL;
ButtonModel DO_DEPEND_MODEL;
ButtonModel COMPILE_ON_SAVE_MODEL;
ButtonModel NO_DEPENDENCIES_MODEL;
Document JAVAC_COMPILER_ARG_MODEL;
Document SCALAC_COMPILER_ARG_MODEL;
// CustomizerCompileTest
// CustomizerJar
Document DIST_JAR_MODEL;
Document BUILD_CLASSES_EXCLUDES_MODEL;
ButtonModel JAR_COMPRESS_MODEL;
ButtonModel DO_JAR_MODEL;
// CustomizerJavadoc
ButtonModel JAVADOC_PRIVATE_MODEL;
ButtonModel JAVADOC_NO_TREE_MODEL;
ButtonModel JAVADOC_USE_MODEL;
ButtonModel JAVADOC_NO_NAVBAR_MODEL;
ButtonModel JAVADOC_NO_INDEX_MODEL;
ButtonModel JAVADOC_SPLIT_INDEX_MODEL;
ButtonModel JAVADOC_AUTHOR_MODEL;
ButtonModel JAVADOC_VERSION_MODEL;
Document JAVADOC_WINDOW_TITLE_MODEL;
ButtonModel JAVADOC_PREVIEW_MODEL;
Document JAVADOC_ADDITIONALPARAM_MODEL;
// CustomizerRun
Map<String/*|null*/,Map<String,String/*|null*/>/*|null*/> RUN_CONFIGS;
String activeConfig;
// CustomizerApplication
Document APPLICATION_TITLE_DOC;
Document APPLICATION_VENDOR_DOC;
Document APPLICATION_DESC_DOC;
Document APPLICATION_HOMEPAGE_DOC;
Document APPLICATION_SPLASH_DOC;
// CustomizerRunTest
// Private fields ----------------------------------------------------------
private J2SEProject project;
private UpdateHelper updateHelper;
private PropertyEvaluator evaluator;
private ReferenceHelper refHelper;
private GeneratedFilesHelper genFileHelper;
private StoreGroup privateGroup;
private StoreGroup projectGroup;
private Map<String,String> additionalProperties;
private String includes, excludes;
J2SEProject getProject() {
return project;
}
/** Creates a new instance of J2SEUIProperties and initializes them */
public J2SEProjectProperties( J2SEProject project, UpdateHelper updateHelper, PropertyEvaluator evaluator, ReferenceHelper refHelper, GeneratedFilesHelper genFileHelper ) {
this.project = project;
this.updateHelper = updateHelper;
this.evaluator = evaluator;
this.refHelper = refHelper;
this.genFileHelper = genFileHelper;
this.cs = new ClassPathSupport(evaluator, refHelper, updateHelper.getAntProjectHelper(), updateHelper, null);
privateGroup = new StoreGroup();
projectGroup = new StoreGroup();
additionalProperties = new HashMap<String,String>();
init(); // Load known properties
}
/** Initializes the visual models
*/
private void init() {
CLASS_PATH_LIST_RENDERER = ClassPathListCellRenderer.createClassPathListRenderer(evaluator, project.getProjectDirectory());
// CustomizerSources
SOURCE_ROOTS_MODEL = SourceRootsUi.createModel( project.getSourceRoots() );
TEST_ROOTS_MODEL = SourceRootsUi.createModel( project.getTestSourceRoots() );
includes = evaluator.getProperty(ProjectProperties.INCLUDES);
if (includes == null) {
includes = "**"; // NOI18N
}
excludes = evaluator.getProperty(ProjectProperties.EXCLUDES);
if (excludes == null) {
excludes = ""; // NOI18N
}
// CustomizerLibraries
EditableProperties projectProperties = updateHelper.getProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH );
JAVAC_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.JAVAC_CLASSPATH)));
JAVAC_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.JAVAC_TEST_CLASSPATH)));
RUN_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.RUN_CLASSPATH)));
RUN_TEST_CLASSPATH_MODEL = ClassPathUiSupport.createListModel(cs.itemsIterator(projectProperties.get(ProjectProperties.RUN_TEST_CLASSPATH)));
PLATFORM_MODEL = PlatformUiSupport.createPlatformComboBoxModel (evaluator.getProperty(JAVA_PLATFORM));
PLATFORM_LIST_RENDERER = PlatformUiSupport.createPlatformListCellRenderer();
JAVAC_SOURCE_MODEL = PlatformUiSupport.createSourceLevelComboBoxModel (PLATFORM_MODEL, evaluator.getProperty(JAVAC_SOURCE), evaluator.getProperty(JAVAC_TARGET));
JAVAC_SOURCE_RENDERER = PlatformUiSupport.createSourceLevelListCellRenderer ();
SHARED_LIBRARIES_MODEL = new PlainDocument();
try {
SHARED_LIBRARIES_MODEL.insertString(0, project.getAntProjectHelper().getLibrariesLocation(), null);
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}
// CustomizerCompile
//JAVAC_DEPRECATION_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVAC_DEPRECATION );
SCALAC_DEPRECATION_MODEL = projectGroup.createToggleButtonModel( evaluator, SCALAC_DEPRECATION );
SCALAC_UNCHECKED_MODEL = projectGroup.createToggleButtonModel( evaluator, SCALAC_UNCHECKED );
//Hotfix of the issue #70058
//Should use the StoreGroup when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
Integer[] kind = new Integer[1];
JAVAC_DEBUG_MODEL = createToggleButtonModel( evaluator, JAVAC_DEBUG, kind);
javacDebugBooleanKind = kind[0];
DO_DEPEND_MODEL = privateGroup.createToggleButtonModel(evaluator, DO_DEPEND);
COMPILE_ON_SAVE_MODEL = privateGroup.createToggleButtonModel(evaluator, COMPILE_ON_SAVE);
NO_DEPENDENCIES_MODEL = projectGroup.createInverseToggleButtonModel( evaluator, NO_DEPENDENCIES );
JAVAC_COMPILER_ARG_MODEL = projectGroup.createStringDocument( evaluator, JAVAC_COMPILER_ARG );
SCALAC_COMPILER_ARG_MODEL = projectGroup.createStringDocument( evaluator, SCALAC_COMPILER_ARG );
// CustomizerJar
DIST_JAR_MODEL = projectGroup.createStringDocument( evaluator, DIST_JAR );
BUILD_CLASSES_EXCLUDES_MODEL = projectGroup.createStringDocument( evaluator, BUILD_CLASSES_EXCLUDES );
JAR_COMPRESS_MODEL = projectGroup.createToggleButtonModel( evaluator, JAR_COMPRESS );
DO_JAR_MODEL = createToggleButtonModel(evaluator, DO_JAR, kind);
doJarBooleanKind = kind[0];
// CustomizerJavadoc
JAVADOC_PRIVATE_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_PRIVATE );
JAVADOC_NO_TREE_MODEL = projectGroup.createInverseToggleButtonModel( evaluator, JAVADOC_NO_TREE );
JAVADOC_USE_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_USE );
JAVADOC_NO_NAVBAR_MODEL = projectGroup.createInverseToggleButtonModel( evaluator, JAVADOC_NO_NAVBAR );
JAVADOC_NO_INDEX_MODEL = projectGroup.createInverseToggleButtonModel( evaluator, JAVADOC_NO_INDEX );
JAVADOC_SPLIT_INDEX_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_SPLIT_INDEX );
JAVADOC_AUTHOR_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_AUTHOR );
JAVADOC_VERSION_MODEL = projectGroup.createToggleButtonModel( evaluator, JAVADOC_VERSION );
JAVADOC_WINDOW_TITLE_MODEL = projectGroup.createStringDocument( evaluator, JAVADOC_WINDOW_TITLE );
//Hotfix of the issue #70058
//Should use the StoreGroup when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
JAVADOC_PREVIEW_MODEL = createToggleButtonModel ( evaluator, JAVADOC_PREVIEW, kind);
javadocPreviewBooleanKind = kind[0];
JAVADOC_ADDITIONALPARAM_MODEL = projectGroup.createStringDocument( evaluator, JAVADOC_ADDITIONALPARAM );
// CustomizerApplication
APPLICATION_TITLE_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_TITLE);
String title = evaluator.getProperty("application.title");
if (title == null) {
try {
APPLICATION_TITLE_DOC.insertString(0, ProjectUtils.getInformation(project).getDisplayName(), null);
} catch (BadLocationException ex) {
// just do not set anything
}
}
APPLICATION_VENDOR_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_VENDOR);
String vendor = evaluator.getProperty("application.vendor");
if (vendor == null) {
try {
APPLICATION_VENDOR_DOC.insertString(0, System.getProperty("user.name", "User Name"), null);
} catch (BadLocationException ex) {
// just do not set anything
}
}
APPLICATION_DESC_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_DESC);
APPLICATION_HOMEPAGE_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_HOMEPAGE);
APPLICATION_SPLASH_DOC = projectGroup.createStringDocument(evaluator, APPLICATION_SPLASH);
// CustomizerRun
RUN_CONFIGS = readRunConfigs();
activeConfig = evaluator.getProperty("config");
}
public void save() {
try {
if ((genFileHelper.getBuildScriptState(GeneratedFilesHelper.BUILD_IMPL_XML_PATH,J2SEProject.class.getResource("resources/build-impl.xsl")) //NOI18N
& GeneratedFilesHelper.FLAG_MODIFIED) == GeneratedFilesHelper.FLAG_MODIFIED) { //NOI18N
//Back up build-impl.xml
final FileObject projectDir = updateHelper.getAntProjectHelper().getProjectDirectory();
final FileObject buildImpl = projectDir.getFileObject(GeneratedFilesHelper.BUILD_IMPL_XML_PATH);
if (buildImpl != null) {
final String name = buildImpl.getName();
final String backupext = String.format("%s~",buildImpl.getExt()); //NOI18N
final FileObject oldBackup = buildImpl.getParent().getFileObject(name, backupext);
if (oldBackup != null) {
oldBackup.delete();
}
FileLock lock = buildImpl.lock();
try {
buildImpl.rename(lock, name, backupext);
} finally {
lock.releaseLock();
}
}
}
saveLibrariesLocation();
// Store properties
ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
public Void run() throws IOException {
storeProperties();
//Delete COS mark
if (!COMPILE_ON_SAVE_MODEL.isSelected()) {
FileObject buildClasses = updateHelper.getAntProjectHelper().resolveFileObject(evaluator.getProperty(ProjectProperties.BUILD_CLASSES_DIR));
if (buildClasses != null) {
FileObject mark = buildClasses.getFileObject(COS_MARK);
if (mark != null) {
final ActionProvider ap = project.getLookup().lookup(ActionProvider.class);
assert ap != null;
ap.invokeAction(ActionProvider.COMMAND_CLEAN, Lookups.fixed(project));
}
}
}
return null;
}
});
// and save the project
ProjectManager.getDefault().saveProject(project);
}
catch (MutexException e) {
ErrorManager.getDefault().notify((IOException)e.getException());
}
catch ( IOException ex ) {
ErrorManager.getDefault().notify( ex );
}
}
private void saveLibrariesLocation() throws IOException, IllegalArgumentException {
try {
String str = SHARED_LIBRARIES_MODEL.getText(0, SHARED_LIBRARIES_MODEL.getLength()).trim();
if (str.length() == 0) {
str = null;
}
String old = project.getAntProjectHelper().getLibrariesLocation();
if ((old == null && str == null) || (old != null && old.equals(str))) {
//ignore, nothing changed..
} else {
project.getAntProjectHelper().setLibrariesLocation(str);
ProjectManager.getDefault().saveProject(project);
}
} catch (BadLocationException x) {
ErrorManager.getDefault().notify(x);
}
}
private void storeProperties() throws IOException {
// Store special properties
// Modify the project dependencies properly
resolveProjectDependencies();
// Encode all paths (this may change the project properties)
String[] javac_cp = cs.encodeToStrings( ClassPathUiSupport.getList( JAVAC_CLASSPATH_MODEL ) );
String[] javac_test_cp = cs.encodeToStrings( ClassPathUiSupport.getList( JAVAC_TEST_CLASSPATH_MODEL ) );
String[] run_cp = cs.encodeToStrings( ClassPathUiSupport.getList( RUN_CLASSPATH_MODEL ) );
String[] run_test_cp = cs.encodeToStrings( ClassPathUiSupport.getList( RUN_TEST_CLASSPATH_MODEL ) );
// Store source roots
storeRoots( project.getSourceRoots(), SOURCE_ROOTS_MODEL );
storeRoots( project.getTestSourceRoots(), TEST_ROOTS_MODEL );
// Store standard properties
EditableProperties projectProperties = updateHelper.getProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH );
EditableProperties privateProperties = updateHelper.getProperties( AntProjectHelper.PRIVATE_PROPERTIES_PATH );
// Assure inegrity which can't shound not be assured in UI
if ( !JAVADOC_NO_INDEX_MODEL.isSelected() ) {
JAVADOC_SPLIT_INDEX_MODEL.setSelected( false ); // Can't split non existing index
}
// Standard store of the properties
projectGroup.store( projectProperties );
privateGroup.store( privateProperties );
storeRunConfigs(RUN_CONFIGS, projectProperties, privateProperties);
EditableProperties ep = updateHelper.getProperties("nbproject/private/config.properties");
if (activeConfig == null) {
ep.remove("config");
} else {
ep.setProperty("config", activeConfig);
}
updateHelper.putProperties("nbproject/private/config.properties", ep);
//Hotfix of the issue #70058
//Should use the StoreGroup when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
//Save javac.debug
privateProperties.setProperty(JAVAC_DEBUG, encodeBoolean (JAVAC_DEBUG_MODEL.isSelected(), javacDebugBooleanKind));
privateProperties.setProperty(DO_JAR, encodeBoolean(DO_JAR_MODEL.isSelected(), doJarBooleanKind));
//Hotfix of the issue #70058
//Should use the StoreGroup when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
//Save javadoc.preview
privateProperties.setProperty(JAVADOC_PREVIEW, encodeBoolean (JAVADOC_PREVIEW_MODEL.isSelected(), javadocPreviewBooleanKind));
// Save all paths
projectProperties.setProperty( ProjectProperties.JAVAC_CLASSPATH, javac_cp );
projectProperties.setProperty( ProjectProperties.JAVAC_TEST_CLASSPATH, javac_test_cp );
projectProperties.setProperty( ProjectProperties.RUN_CLASSPATH, run_cp );
projectProperties.setProperty( ProjectProperties.RUN_TEST_CLASSPATH, run_test_cp );
//Handle platform selection and javac.source javac.target properties
PlatformUiSupport.storePlatform (projectProperties, updateHelper, J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, PLATFORM_MODEL.getSelectedItem(), JAVAC_SOURCE_MODEL.getSelectedItem());
// Handle other special cases
if ( NO_DEPENDENCIES_MODEL.isSelected() ) { // NOI18N
projectProperties.remove( NO_DEPENDENCIES ); // Remove the property completely if not set
}
projectProperties.putAll(additionalProperties);
projectProperties.put(ProjectProperties.INCLUDES, includes);
projectProperties.put(ProjectProperties.EXCLUDES, excludes);
// Store the property changes into the project
updateHelper.putProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH, projectProperties );
updateHelper.putProperties( AntProjectHelper.PRIVATE_PROPERTIES_PATH, privateProperties );
String value = additionalProperties.get(SOURCE_ENCODING);
if (value != null) {
try {
FileEncodingQuery.setDefaultEncoding(Charset.forName(value));
} catch (UnsupportedCharsetException e) {
//When the encoding is not supported by JVM do not set it as default
}
}
}
/** Finds out what are new and removed project dependencies and
* applyes the info to the project
*/
private void resolveProjectDependencies() {
// Create a set of old and new artifacts.
Set<ClassPathSupport.Item> oldArtifacts = new HashSet<ClassPathSupport.Item>();
EditableProperties projectProperties = updateHelper.getProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH );
oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.JAVAC_CLASSPATH ) ) );
oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.JAVAC_TEST_CLASSPATH ) ) );
oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.RUN_CLASSPATH ) ) );
oldArtifacts.addAll( cs.itemsList( projectProperties.get( ProjectProperties.RUN_TEST_CLASSPATH ) ) );
Set<ClassPathSupport.Item> newArtifacts = new HashSet<ClassPathSupport.Item>();
newArtifacts.addAll( ClassPathUiSupport.getList( JAVAC_CLASSPATH_MODEL ) );
newArtifacts.addAll( ClassPathUiSupport.getList( JAVAC_TEST_CLASSPATH_MODEL ) );
newArtifacts.addAll( ClassPathUiSupport.getList( RUN_CLASSPATH_MODEL ) );
newArtifacts.addAll( ClassPathUiSupport.getList( RUN_TEST_CLASSPATH_MODEL ) );
// Create set of removed artifacts and remove them
Set<ClassPathSupport.Item> removed = new HashSet<ClassPathSupport.Item>(oldArtifacts);
removed.removeAll( newArtifacts );
Set<ClassPathSupport.Item> added = new HashSet<ClassPathSupport.Item>(newArtifacts);
added.removeAll(oldArtifacts);
// 1. first remove all project references. The method will modify
// project property files, so it must be done separately
for (ClassPathSupport.Item item : removed) {
if ( item.getType() == ClassPathSupport.Item.TYPE_ARTIFACT ||
item.getType() == ClassPathSupport.Item.TYPE_JAR ) {
refHelper.destroyReference(item.getReference());
if (item.getType() == ClassPathSupport.Item.TYPE_JAR) {
item.removeSourceAndJavadoc(updateHelper);
}
}
}
boolean changed = false;
// 2. now read project.properties and modify rest
EditableProperties ep = updateHelper.getProperties( AntProjectHelper.PROJECT_PROPERTIES_PATH );
for (ClassPathSupport.Item item : removed) {
if (item.getType() == ClassPathSupport.Item.TYPE_LIBRARY) {
// remove helper property pointing to library jar if there is any
String prop = item.getReference();
prop = CommonProjectUtils.getAntPropertyName(prop);
ep.remove(prop);
changed = true;
}
}
if (changed) {
updateHelper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
}
}
private void storeRoots( SourceRoots roots, DefaultTableModel tableModel ) throws MalformedURLException {
Vector data = tableModel.getDataVector();
URL[] rootURLs = new URL[data.size()];
String []rootLabels = new String[data.size()];
for (int i=0; i<data.size();i++) {
File f = (File) ((Vector)data.elementAt(i)).elementAt(0);
rootURLs[i] = J2SEProjectUtil.getRootURL(f,null);
rootLabels[i] = (String) ((Vector)data.elementAt(i)).elementAt(1);
}
roots.putRoots(rootURLs,rootLabels);
}
/* This is used by CustomizerWSServiceHost */
public void putAdditionalProperty(String propertyName, String propertyValue) {
additionalProperties.put(propertyName, propertyValue);
}
//Hotfix of the issue #70058
//Should be removed when the StoreGroup SPI will be extended to allow false default value in ToggleButtonModel
private static String encodeBoolean (boolean value, Integer kind) {
if ( kind == BOOLEAN_KIND_ED ) {
return value ? "on" : "off"; // NOI18N
}
else if ( kind == BOOLEAN_KIND_YN ) { // NOI18N
return value ? "yes" : "no";
}
else {
return value ? "true" : "false"; // NOI18N
}
}
//Hotfix of the issue #70058
//Should be removed when the StoreGroup SPI will be extended to allow true default value in ToggleButtonModel
private static JToggleButton.ToggleButtonModel createToggleButtonModel (final PropertyEvaluator evaluator, final String propName, Integer[] kind) {
assert evaluator != null && propName != null && kind != null && kind.length == 1;
String value = evaluator.getProperty( propName );
boolean isSelected = false;
if (value == null) {
isSelected = true;
}
else {
String lowercaseValue = value.toLowerCase();
if ( lowercaseValue.equals( "yes" ) || lowercaseValue.equals( "no" ) ) { // NOI18N
kind[0] = BOOLEAN_KIND_YN;
}
else if ( lowercaseValue.equals( "on" ) || lowercaseValue.equals( "off" ) ) { // NOI18N
kind[0] = BOOLEAN_KIND_ED;
}
else {
kind[0] = BOOLEAN_KIND_TF;
}
if ( lowercaseValue.equals( "true") || // NOI18N
lowercaseValue.equals( "yes") || // NOI18N
lowercaseValue.equals( "on") ) { // NOI18N
isSelected = true;
}
}
JToggleButton.ToggleButtonModel bm = new JToggleButton.ToggleButtonModel();
bm.setSelected(isSelected );
return bm;
}
/**
* A mess.
*/
Map<String/*|null*/,Map<String,String>> readRunConfigs() {
Map<String,Map<String,String>> m = new TreeMap<String,Map<String,String>>(new Comparator<String>() {
public int compare(String s1, String s2) {
return s1 != null ? (s2 != null ? s1.compareTo(s2) : 1) : (s2 != null ? -1 : 0);
}
});
Map<String,String> def = new TreeMap<String,String>();
for (String prop : new String[] {MAIN_CLASS, APPLICATION_ARGS, RUN_JVM_ARGS, RUN_WORK_DIR}) {
String v = updateHelper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH).getProperty(prop);
if (v == null) {
v = updateHelper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH).getProperty(prop);
}
if (v != null) {
def.put(prop, v);
}
}
m.put(null, def);
FileObject configs = project.getProjectDirectory().getFileObject("nbproject/configs");
if (configs != null) {
for (FileObject kid : configs.getChildren()) {
if (!kid.hasExt("properties")) {
continue;
}
m.put(kid.getName(), new TreeMap<String,String>(updateHelper.getProperties(FileUtil.getRelativePath(project.getProjectDirectory(), kid))));
}
}
configs = project.getProjectDirectory().getFileObject("nbproject/private/configs");
if (configs != null) {
for (FileObject kid : configs.getChildren()) {
if (!kid.hasExt("properties")) {
continue;
}
Map<String,String> c = m.get(kid.getName());
if (c == null) {
continue;
}
c.putAll(new HashMap<String,String>(updateHelper.getProperties(FileUtil.getRelativePath(project.getProjectDirectory(), kid))));
}
}
//System.err.println("readRunConfigs: " + m);
return m;
}
/**
* A royal mess.
*/
void storeRunConfigs(Map<String/*|null*/,Map<String,String/*|null*/>/*|null*/> configs,
EditableProperties projectProperties, EditableProperties privateProperties) throws IOException {
//System.err.println("storeRunConfigs: " + configs);
Map<String,String> def = configs.get(null);
for (String prop : new String[] {MAIN_CLASS, APPLICATION_ARGS, RUN_JVM_ARGS, RUN_WORK_DIR}) {
String v = def.get(prop);
EditableProperties ep = (prop.equals(APPLICATION_ARGS) || prop.equals(RUN_WORK_DIR)) ?
privateProperties : projectProperties;
if (!Utilities.compareObjects(v, ep.getProperty(prop))) {
if (v != null && v.length() > 0) {
ep.setProperty(prop, v);
} else {
ep.remove(prop);
}
}
}
for (Map.Entry<String,Map<String,String>> entry : configs.entrySet()) {
String config = entry.getKey();
if (config == null) {
continue;
}
String sharedPath = "nbproject/configs/" + config + ".properties"; // NOI18N
String privatePath = "nbproject/private/configs/" + config + ".properties"; // NOI18N
Map<String,String> c = entry.getValue();
if (c == null) {
updateHelper.putProperties(sharedPath, null);
updateHelper.putProperties(privatePath, null);
continue;
}
for (Map.Entry<String,String> entry2 : c.entrySet()) {
String prop = entry2.getKey();
String v = entry2.getValue();
String path = (prop.equals(APPLICATION_ARGS) || prop.equals(RUN_WORK_DIR)) ?
privatePath : sharedPath;
EditableProperties ep = updateHelper.getProperties(path);
if (!Utilities.compareObjects(v, ep.getProperty(prop))) {
if (v != null && (v.length() > 0 || (def.get(prop) != null && def.get(prop).length() > 0))) {
ep.setProperty(prop, v);
} else {
ep.remove(prop);
}
updateHelper.putProperties(path, ep);
}
}
// Make sure the definition file is always created, even if it is empty.
updateHelper.putProperties(sharedPath, updateHelper.getProperties(sharedPath));
}
}
void loadIncludesExcludes(IncludeExcludeVisualizer v) {
Set<File> roots = new HashSet<File>();
for (DefaultTableModel model : new DefaultTableModel[] {SOURCE_ROOTS_MODEL, TEST_ROOTS_MODEL}) {
for (Object row : model.getDataVector()) {
File d = (File) ((Vector) row).elementAt(0);
if (/* #104996 */d.isDirectory()) {
roots.add(d);
}
}
}
v.setRoots(roots.toArray(new File[roots.size()]));
v.setIncludePattern(includes);
v.setExcludePattern(excludes);
}
void storeIncludesExcludes(IncludeExcludeVisualizer v) {
includes = v.getIncludePattern();
excludes = v.getExcludePattern();
}
boolean makeSharable() {
List<String> libs = new ArrayList<String>();
List<String> jars = new ArrayList<String>();
collectLibs(JAVAC_CLASSPATH_MODEL, libs, jars);
collectLibs(JAVAC_TEST_CLASSPATH_MODEL, libs, jars);
collectLibs(RUN_CLASSPATH_MODEL, libs, jars);
collectLibs(RUN_TEST_CLASSPATH_MODEL, libs, jars);
libs.add("CopyLibs"); // #132201 - copylibs is integral part of j2seproject
String customTasksLibs = getProject().evaluator().getProperty(AntBuildExtender.ANT_CUSTOMTASKS_LIBS_PROPNAME);
if (customTasksLibs != null) {
String libIDs[] = customTasksLibs.split(",");
for (String libID : libIDs) {
libs.add(libID.trim());
}
}
return SharableLibrariesUtils.showMakeSharableWizard(getProject().getAntProjectHelper(),
getProject().getReferenceHelper(), libs, jars);
}
private void collectLibs(DefaultListModel model, List<String> libs, List<String> jarReferences) {
for (int i = 0; i < model.size(); i++) {
ClassPathSupport.Item item = (ClassPathSupport.Item) model.get(i);
if (item.getType() == ClassPathSupport.Item.TYPE_LIBRARY) {
if (!item.isBroken() && !libs.contains(item.getLibrary().getName())) {
libs.add(item.getLibrary().getName());
}
}
if (item.getType() == ClassPathSupport.Item.TYPE_JAR) {
if (item.getReference() != null && item.getVariableBasedProperty() == null && !jarReferences.contains(item.getReference())) {
//TODO reference is null for not yet persisted items.
// there seems to be no way to generate a reference string without actually
// creating and writing the property..
jarReferences.add(item.getReference());
}
}
}
}
}