001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 2004-2005 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.jmx.runtime;
042:
043: import org.netbeans.api.java.classpath.ClassPath;
044: import org.netbeans.api.java.classpath.GlobalPathRegistry;
045:
046: import org.netbeans.api.project.Project;
047: import org.netbeans.api.project.ProjectManager;
048:
049: import org.netbeans.spi.project.AuxiliaryConfiguration;
050:
051: import org.netbeans.spi.project.support.ant.AntProjectHelper;
052: import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
053:
054: import org.openide.util.Mutex;
055: import org.openide.NotifyDescriptor;
056: import org.openide.filesystems.FileLock;
057: import org.openide.filesystems.FileObject;
058: import org.openide.filesystems.FileUtil;
059: import org.openide.modules.InstalledFileLocator;
060: import org.openide.util.MutexException;
061: import org.openide.xml.XMLUtil;
062: import org.w3c.dom.Element;
063:
064: import org.openide.util.NbBundle;
065:
066: import java.io.*;
067: import java.util.Properties;
068:
069: import java.util.Set;
070: import java.util.Iterator;
071: import java.util.Map;
072: import org.netbeans.api.java.platform.JavaPlatform;
073: import org.netbeans.api.java.platform.JavaPlatformManager;
074: import org.netbeans.api.java.platform.Specification;
075: import org.netbeans.modules.jmx.j2seproject.customizer.MonitoringPanel;
076: import org.openide.modules.SpecificationVersion;
077:
078: public class J2SEProjectType {
079:
080: private static final String J2SE_PROJECT_NAMESPACE_40 = "http://www.netbeans.org/ns/j2se-project/1";// NOI18N
081: private static final String J2SE_PROJECT_NAMESPACE_41 = "http://www.netbeans.org/ns/j2se-project/2";// NOI18N
082: private static final String J2SE_PROJECT_NAMESPACE_50 = "http://www.netbeans.org/ns/j2se-project/3";// NOI18N
083:
084: private static final String STANDARD_IMPORT_STRING = "<import file=\"nbproject/build-impl.xml\"/>";// NOI18N
085: private static final String MANAGEMENT_IMPORT_STRING = "<import file=\"nbproject/management-build-impl.xml\"/>";// NOI18N
086: private static final String MANAGEMENT_NAME_SPACE = "http://www.netbeans.org/ns/jmx/1";// NOI18N
087: private static SpecificationVersion JDK15Version = new SpecificationVersion(
088: "1.5");// NOI18N
089:
090: public static boolean isProjectTypeSupported(Project project) {
091: AuxiliaryConfiguration aux = (AuxiliaryConfiguration) project
092: .getLookup().lookup(AuxiliaryConfiguration.class);
093: if (aux == null) {
094: System.err
095: .println("Auxiliary Configuration is null for Project: "
096: + project);// NOI18N
097: return false;
098: }
099: Element e = aux.getConfigurationFragment("data",
100: J2SE_PROJECT_NAMESPACE_50, true);// NOI18N
101: if (e == null) {
102: e = aux.getConfigurationFragment("data",
103: J2SE_PROJECT_NAMESPACE_40, true);// NOI18N
104: if (e == null) {
105: e = aux.getConfigurationFragment("data",
106: J2SE_PROJECT_NAMESPACE_41, true); // NOI18N
107: }
108: }
109: return (e != null);
110: }
111:
112: public static boolean isPlatformGreaterThanJDK15(Project project) {
113: Properties projectProperties = getProjectProperties(project);
114: JavaPlatform platform = null;
115: String platformName = projectProperties
116: .getProperty("platform.active");// NOI18N
117:
118: if (platformName == null
119: || platformName.equals("default_platform"))// NOI18N
120: platform = JavaPlatformManager.getDefault()
121: .getDefaultPlatform();
122: else {
123: JavaPlatform[] installedPlatforms = JavaPlatformManager
124: .getDefault().getPlatforms(null,
125: new Specification("j2se", null)); //NOI18N
126: for (int i = 0; i < installedPlatforms.length; i++) {
127: String antName = (String) installedPlatforms[i]
128: .getProperties().get("platform.ant.name"); //NOI18N
129: if (antName != null && antName.equals(platformName)) {
130: platform = installedPlatforms[i];
131: }
132: }
133: }
134: return JDK15Version.compareTo(platform.getSpecification()
135: .getVersion()) < 0;
136: }
137:
138: public static boolean checkProjectCanBeManaged(Project project) {
139: Properties pp = getProjectProperties(project);
140: String mainClass = pp.getProperty("main.class");// NOI18N
141: boolean res = false;
142: if (mainClass != null && !"".equals(mainClass)) {// NOI18N
143: FileObject fo = findFileForClass(mainClass, true);
144: if (fo != null)
145: res = true;
146: }
147: if (!res) {
148: ManagementDialogs.getDefault().notify(
149: new NotifyDescriptor.Message(NbBundle.getMessage(
150: J2SEProjectType.class,
151: "ERR_MainClassNotSet"),
152: NotifyDescriptor.WARNING_MESSAGE));// NOI18N
153:
154: return false;
155: }
156: return true;
157: }
158:
159: public static FileObject findFileForClass(String className,
160: boolean tryInnerclasses) {
161: FileObject fo = null;
162: try {
163: String resourceName = className.replaceAll("\\.", "/")
164: + ".java"; //NOI18N
165: GlobalPathRegistry gpr = GlobalPathRegistry.getDefault();
166: Set paths = gpr.getPaths("classpath/source"); //NOI18N
167: for (Iterator iterator = paths.iterator(); iterator
168: .hasNext();) {
169: ClassPath cp = (ClassPath) iterator.next();
170: fo = cp.findResource(resourceName);
171: if (fo != null)
172: break;
173: }
174: } catch (Exception e) {
175: e.printStackTrace(System.err);
176: }
177: if ((fo == null) && tryInnerclasses) {
178: // not found - will try without last .xxx to see if the last name is not an innerclass name
179: int dotIndex = className.lastIndexOf('.');
180: if (dotIndex != -1)
181: return findFileForClass(className
182: .substring(0, dotIndex), true);
183: }
184: return fo;
185: }
186:
187: public static boolean checkProjectIsModifiedForManagement(
188: Project project) {
189: Element e = ((AuxiliaryConfiguration) project.getLookup()
190: .lookup(AuxiliaryConfiguration.class))
191: .getConfigurationFragment("data",
192: MANAGEMENT_NAME_SPACE, true);// NOI18N
193: if (e != null)
194: return true; // already modified, nothing more to do
195:
196: if (ManagementDialogs.getDefault().notify(
197: new NotifyDescriptor.Confirmation(NbBundle.getMessage(
198: J2SEProjectType.class, "WARN_BUILD_UPDATE"), // NOI18N
199: NotifyDescriptor.OK_CANCEL_OPTION)) != NotifyDescriptor.OK_OPTION) {
200: return false; // cancelled by the user
201: }
202:
203: Element mgtFragment = XMLUtil.createDocument("ignore", null,
204: null, null).createElementNS(MANAGEMENT_NAME_SPACE,
205: "data");// NOI18N
206: mgtFragment.setAttribute("version", "0.4");// NOI18N
207: ((AuxiliaryConfiguration) project.getLookup().lookup(
208: AuxiliaryConfiguration.class))
209: .putConfigurationFragment(mgtFragment, true);
210: try {
211: ProjectManager.getDefault().saveProject(project);
212: } catch (IOException e1) {
213: e1.printStackTrace(System.err);
214: return false;
215: }
216:
217: try {
218: GeneratedFilesHelper gfh = new GeneratedFilesHelper(project
219: .getProjectDirectory());
220: gfh.refreshBuildScript(
221: "nbproject/management-build-impl.xml",
222: J2SEProjectType.class
223: .getResource("management-build-impl.xsl"),
224: false);// NOI18N
225: } catch (IOException e1) {
226: return false;
227: }
228:
229: String buildScript = ProjectUtilities
230: .getProjectBuildScript(project);
231:
232: if (buildScript == null) {
233: ManagementDialogs.getDefault().notify(
234: new NotifyDescriptor.Message(NbBundle.getMessage(
235: J2SEProjectType.class,
236: "ERR_BUILD_NOT_FOUND"), // NOI18N
237: NotifyDescriptor.ERROR_MESSAGE));
238: return false;
239: }
240:
241: if (!ProjectUtilities.backupBuildScript(project)) {
242: if (ManagementDialogs.getDefault().notify(
243: new NotifyDescriptor.Confirmation(
244: NbBundle.getMessage(J2SEProjectType.class,
245: "ERR_BUILD_NOT_BACKUP"), // NOI18N
246: NotifyDescriptor.OK_CANCEL_OPTION,
247: NotifyDescriptor.WARNING_MESSAGE)) != NotifyDescriptor.OK_OPTION) {
248: return false; // cancelled by the user
249: }
250: }
251:
252: StringBuffer newDataBuffer = new StringBuffer(buildScript
253: .length() + 200);
254: int importIndex = buildScript.indexOf(STANDARD_IMPORT_STRING);
255: if (importIndex == -1) {
256: // notify the user that the build script cannot be modified, and he should perform the change himself
257: ManagementDialogs.getDefault().notify(
258: new NotifyDescriptor.Message(NbBundle.getMessage(
259: J2SEProjectType.class,
260: "ERR_BUILD_NOT_UPDATED"), // NOI18N
261: NotifyDescriptor.WARNING_MESSAGE));
262: return false;
263: }
264: String indent = "";// NOI18N
265: int idx = importIndex - 1;
266: while (idx >= 0) {
267: if (buildScript.charAt(idx) == ' ')
268: indent = " " + indent;// NOI18N
269: else if (buildScript.charAt(idx) == '\t')
270: indent = "\t" + indent;// NOI18N
271: else
272: break;
273: idx--;
274: }
275: newDataBuffer.append(buildScript.substring(0, importIndex
276: + STANDARD_IMPORT_STRING.length() + 1));
277: newDataBuffer.append("\n");// NOI18N
278: newDataBuffer.append(indent);
279: newDataBuffer.append(MANAGEMENT_IMPORT_STRING);
280: newDataBuffer.append(buildScript.substring(importIndex
281: + STANDARD_IMPORT_STRING.length() + 1));
282:
283: FileObject buildFile = project.getProjectDirectory()
284: .getFileObject("build.xml");// NOI18N
285: FileLock lock = null;
286: PrintWriter writer = null;
287: try {
288: lock = buildFile.lock();
289: writer = new PrintWriter(buildFile.getOutputStream(lock));
290: writer.println(newDataBuffer.toString());
291:
292: } catch (FileNotFoundException e1) {
293: e1.printStackTrace(System.err);
294: } catch (IOException e1) {
295: e1.printStackTrace(System.err);
296: } finally {
297: lock.releaseLock();
298: if (writer != null)
299: writer.close();
300: }
301: return true;
302: }
303:
304: public static void overwriteProperty(Project project,
305: final String key, final String value) throws Exception {
306: FileObject privatePropsFile = project
307: .getProjectDirectory()
308: .getFileObject(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
309: final File projectPropsFile = FileUtil.toFile(project
310: .getProjectDirectory().getFileObject(
311: AntProjectHelper.PROJECT_PROPERTIES_PATH));
312: ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() {
313: public Object run() throws Exception {
314: java.util.Properties p = new java.util.Properties();
315:
316: FileInputStream fis = new FileInputStream(
317: projectPropsFile);
318: try {
319: p.load(fis);
320: p.setProperty(key, value);
321: } finally {
322: fis.close();
323: }
324: FileOutputStream fos = new FileOutputStream(
325: projectPropsFile);
326: try {
327: p.store(fos, null);
328: } finally {
329: fos.close();
330: }
331: return null;
332: }
333: });
334: }
335:
336: public static void addProjectProperties(final Map properties,
337: Project project) throws MutexException {
338: FileObject privatePropsFile = project
339: .getProjectDirectory()
340: .getFileObject(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
341: final File projectPropsFile = FileUtil.toFile(project
342: .getProjectDirectory().getFileObject(
343: AntProjectHelper.PROJECT_PROPERTIES_PATH));
344: ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() {
345: public Object run() throws Exception {
346: java.util.Properties p = new java.util.Properties();
347:
348: FileInputStream fis = new FileInputStream(
349: projectPropsFile);
350: try {
351: p.load(fis);
352: p.putAll(properties);
353: } finally {
354: fis.close();
355: }
356: FileOutputStream fos = new FileOutputStream(
357: projectPropsFile);
358: try {
359: p.store(fos, null);
360: } finally {
361: fos.close();
362: }
363: return null;
364: }
365: });
366: }
367:
368: public static Properties getProjectProperties(Project project) {
369: Properties props = new Properties();
370: FileObject privatePropsFile = project
371: .getProjectDirectory()
372: .getFileObject(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
373: FileObject projectPropsFile = project
374: .getProjectDirectory()
375: .getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH);
376: File userPropsFile = InstalledFileLocator.getDefault().locate(
377: "build.properties", null, false);// NOI18N
378:
379: // the order is 1. private, 2. project, 3. user to reflect how Ant handles property definitions (immutable, once set property value cannot be changed)
380: if (privatePropsFile != null) {
381: try {
382: InputStream is = privatePropsFile.getInputStream();
383: try {
384: props.load(is);
385: } finally {
386: is.close();
387: }
388: } catch (IOException e) {
389: e.printStackTrace();
390: }
391: }
392:
393: if (projectPropsFile != null) {
394: try {
395: InputStream is = projectPropsFile.getInputStream();
396: try {
397: props.load(is);
398: } finally {
399: is.close();
400: }
401: } catch (IOException e) {
402: e.printStackTrace();
403: }
404: }
405:
406: if (userPropsFile != null) {
407: try {
408: InputStream is = new BufferedInputStream(
409: new FileInputStream(userPropsFile));
410: try {
411: props.load(is);
412: } finally {
413: is.close();
414: }
415: } catch (IOException e) {
416: e.printStackTrace();
417: }
418: }
419: return props;
420: }
421: }
|