blob: 8e2097b383e5eada3fd470dcb0a3f906fc41fcaa [file] [log] [blame]
/*
* 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.openide.execution;
import java.io.File;
import java.util.*;
import org.openide.filesystems.*;
import org.openide.util.Lookup;
/** Property that can hold informations about class path and
* that can be used to create string representation of the
* class path.
*/
public final class NbClassPath extends Object implements java.io.Serializable {
/** A JDK 1.1 serial version UID */
static final long serialVersionUID = -8458093409814321744L;
/** Fuj: This is the most overloaded variable in this class.
* It can hold Object[] with elements of String or Exception
* or later Exception[] array.
*
* Also the array can hold File[] array.
*/
private Object[] items;
/** the prepared classpath */
private String classpath;
/** Create a new descriptor for the specified process, classpath switch, and classpath.
* @param classpathItems the classpath to be passed to the process
*/
public NbClassPath (String[] classpathItems) {
this.items = classpathItems;
}
/** Create a new descriptor for the specified process, classpath switch, and classpath.
* @param classpathItems the classpath to be passed to the process
*/
public NbClassPath (File[] classpathItems) {
this.items = classpathItems;
}
/** Private constructor
* @param arr array of String and Exceptions
*/
NbClassPath (Object[] arr) {
this.items = arr;
}
/** Create a class path from the usual string representation.
* @param path a class path separated by {@link File#pathSeparatorChar}s
*/
public NbClassPath (String path) {
this.items = new Exception[0];
this.classpath = path;
// [PENDING] what is this here for? *Users* of the classpath should quote it as needed to
// pass thru shells, according to the type of shell. Right?
if (path.indexOf(' ') >= 0) {
if (path.startsWith("\"")) { // NOI18N
return;
} else {
StringBuffer buff = new StringBuffer(path);
buff.insert(0, '"');
buff.append('"');
classpath = buff.toString();
}
}
}
/** Creates class path describing additional libraries needed by the system.
* Never use this class path as part of a user project!
* For more information consult the <a href="../doc-files/classpath.html">Module Class Path</a> document.
* @deprecated There are generally no excuses to be using this method as part of a normal module;
* its exact meaning is vague, and probably not what you want.
*/
public static NbClassPath createLibraryPath () {
Thread.dumpStack();
// modules & libs
ExecutionEngine ee = (ExecutionEngine)Lookup.getDefault().lookup(ExecutionEngine.class);
if (ee != null) {
return ee.createLibraryPath();
} else {
return new NbClassPath(new File[0]);
}
}
/** Creates class path of the system.
* Never use this class path as part of a user project!
* For more information consult the <a href="../doc-files/classpath.html">Module Class Path</a> document.
* @deprecated There are generally no excuses to be using this method as part of a normal module;
* its exact meaning is vague, and probably not what you want.
*/
public static NbClassPath createClassPath () {
Thread.dumpStack();
// ${java.class.path} minus openide-compat.jar
String cp = System.getProperty ("java.class.path"); // NOI18N
if (cp == null || cp.length () == 0) return new NbClassPath (""); // NOI18N
StringBuffer buf = new StringBuffer (cp.length ());
StringTokenizer tok = new StringTokenizer (cp, File.pathSeparator);
boolean appended = false;
while (tok.hasMoreTokens ()) {
String piece = tok.nextToken ();
if (piece.endsWith ("openide-compat.jar")) continue; // NOI18N
if (appended) {
buf.append (File.pathSeparatorChar);
} else {
appended = true;
}
buf.append (piece);
}
return new NbClassPath (buf.toString ());
}
/** Creates path describing boot class path of the system.
* Never use this class path as part of a user project!
* There are generally no excuses to be using this method as part of a normal module.
* For more information consult the <a href="../doc-files/classpath.html">Module Class Path</a> document.
* @return class path of system class including extensions
* @deprecated Use the Java Platform API instead.
*/
public static NbClassPath createBootClassPath () {
Thread.dumpStack();
// boot
String boot = System.getProperty("sun.boot.class.path"); // NOI18N
StringBuffer sb = (boot != null ? new StringBuffer(boot) : new StringBuffer());
// std extensions
String extensions = System.getProperty("java.ext.dirs"); // NOI18N
if (extensions != null) {
for (StringTokenizer st = new StringTokenizer(extensions, File.pathSeparator); st.hasMoreTokens();) {
File dir = new File(st.nextToken());
File[] entries = dir.listFiles();
if (entries != null) {
for (int i = 0; i < entries.length; i++) {
String name = entries[i].getName().toLowerCase(Locale.US);
if (name.endsWith(".zip") || name.endsWith(".jar")) { // NOI18N
if (sb.length() > 0) {
sb.append(File.pathSeparatorChar);
}
sb.append(entries[i].getPath());
}
}
}
}
}
return new NbClassPath (sb.toString());
}
/** Take one file object and try to convert it into a local file.
* @param fo file object to convert
* @return disk file for that file object, or <code>null</code> if there is no corresponding disk file
* @deprecated You should use {@link org.openide.filesystems.FileUtil#toFile} instead.
*/
public static File toFile (FileObject fo) {
Thread.dumpStack();
return FileUtil.toFile(fo);
}
/** If there were some problems during creation of the class path, they can be identified
* by asking the method. So this method can be called to test whether it is correct to
* use the path or there can be some errors.
* <P>
* This can happen especially when creating NbClassPath for filesystems in repository and
* they are not stored on locally accessible disks.
*
* @return array of exceptions thrown during creation of the path
*/
public Exception[] getExceptions () {
try {
return (Exception[])items;
} catch (ClassCastException ex) {
// we have to convert the array first
}
synchronized (this) {
// creates class path
getClassPath ();
int first = 0;
for (int i = 0; i < items.length; i++) {
if (items[i] != null) {
// should be exception
items[first++] = items[i];
}
}
Exception[] list = new Exception[first];
System.arraycopy (items, 0, list, 0, first);
items = list;
return list;
}
}
/** Create class path representation. The implementation <i>will return the string quoted
* (using doublequotes)</i>, if it contains a space character.
* @return string representing the classpath items separated by File.separatorChar, possibly quoted.
*/
public String getClassPath () {
if (classpath != null) return classpath;
synchronized (this) {
if (classpath != null) return classpath;
if (items.length == 0) {
return classpath = ""; // NOI18N
} else {
StringBuffer sb = new StringBuffer ();
boolean haveone = false;
for (int i = 0; i < items.length; i++) {
Object o = items[i];
if (o == null || (! (o instanceof String) && ! (o instanceof File))) {
// we accept only strings/files
continue;
}
if (haveone) {
sb.append (File.pathSeparatorChar);
} else {
haveone = true;
}
sb.append (o.toString ());
items[i] = null;
}
String clsPth;
if ((clsPth = sb.toString()).indexOf(' ') >= 0) {
sb.insert(0, '"');
sb.append('"');
classpath = sb.toString();
} else {
classpath = clsPth;
}
return classpath;
}
}
}
/* equals */
public boolean equals(Object o) {
if (! (o instanceof NbClassPath)) return false;
NbClassPath him = (NbClassPath) o;
return getClassPath ().equals (him.getClassPath ());
}
}