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 1997-2006 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:
042: package org.netbeans.modules.ruby.rubyproject;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.util.ArrayList;
047: import java.util.Arrays;
048: import java.util.Iterator;
049: import java.util.List;
050: import javax.swing.JComboBox;
051: import org.netbeans.api.project.Project;
052: import org.netbeans.api.project.ProjectManager;
053: import org.netbeans.modules.ruby.platform.PlatformComponentFactory;
054: import org.netbeans.spi.project.AuxiliaryConfiguration;
055: import org.netbeans.modules.ruby.spi.project.support.rake.RakeProjectHelper;
056: import org.netbeans.modules.ruby.spi.project.support.rake.PropertyEvaluator;
057: import org.netbeans.modules.ruby.spi.project.support.rake.PropertyUtils;
058: import org.openide.ErrorManager;
059: import org.w3c.dom.Element;
060: import org.w3c.dom.Node;
061: import org.w3c.dom.NodeList;
062: import org.w3c.dom.Text;
063:
064: /**
065: * This was originally org.netbeans.modules.ant.freeform.spi.support.Util
066: * Miscellaneous helper methods.
067: * @author Jesse Glick, David Konecny
068: */
069: public final class Util {
070:
071: private static final String LAST_PLATFORM_ID = "projectPanelLastPlatformID"; // NOI18N
072:
073: private Util() {
074: }
075:
076: // XXX XML methods copied from ant/project... make a general API of these instead?
077:
078: /**
079: * Search for an XML element in the direct children of a parent.
080: * DOM provides a similar method but it does a recursive search
081: * which we do not want. It also gives a node list and we want
082: * only one result.
083: * @param parent a parent element
084: * @param name the intended local name
085: * @param namespace the intended namespace
086: * @return the one child element with that name, or null if none or more than one
087: */
088: public static Element findElement(Element parent, String name,
089: String namespace) {
090: Element result = null;
091: NodeList l = parent.getChildNodes();
092: for (int i = 0; i < l.getLength(); i++) {
093: if (l.item(i).getNodeType() == Node.ELEMENT_NODE) {
094: Element el = (Element) l.item(i);
095: if (name.equals(el.getLocalName())
096: && namespace.equals(el.getNamespaceURI())) {
097: if (result == null) {
098: result = el; // XXX Uhm, why don't we just return it???
099: } else {
100: return null;
101: }
102: }
103: }
104: }
105: return result;
106: }
107:
108: /**
109: * Extract nested text from an element.
110: * Currently does not handle coalescing text nodes, CDATA sections, etc.
111: * @param parent a parent element
112: * @return the nested text, or null if none was found
113: */
114: public static String findText(Element parent) {
115: NodeList l = parent.getChildNodes();
116: for (int i = 0; i < l.getLength(); i++) {
117: if (l.item(i).getNodeType() == Node.TEXT_NODE) {
118: Text text = (Text) l.item(i);
119: return text.getNodeValue();
120: }
121: }
122: return null;
123: }
124:
125: /**
126: * Find all direct child elements of an element.
127: * More useful than {@link Element#getElementsByTagNameNS} because it does
128: * not recurse into recursive child elements.
129: * Children which are all-whitespace text nodes are ignored; others cause
130: * an exception to be thrown.
131: * @param parent a parent element in a DOM tree
132: * @return a list of direct child elements (may be empty)
133: * @throws IllegalArgumentException if there are non-element children besides whitespace
134: */
135: public static List<Element> findSubElements(Element parent)
136: throws IllegalArgumentException {
137: NodeList l = parent.getChildNodes();
138: List<Element> elements = new ArrayList<Element>(l.getLength());
139: for (int i = 0; i < l.getLength(); i++) {
140: Node n = l.item(i);
141: if (n.getNodeType() == Node.ELEMENT_NODE) {
142: elements.add((Element) n);
143: } else if (n.getNodeType() == Node.TEXT_NODE) {
144: String text = ((Text) n).getNodeValue();
145: if (text.trim().length() > 0) {
146: throw new IllegalArgumentException(
147: "non-ws text encountered in " + parent
148: + ": " + text); // NOI18N
149: }
150: } else if (n.getNodeType() == Node.COMMENT_NODE) {
151: // skip
152: } else {
153: throw new IllegalArgumentException(
154: "unexpected non-element child of " + parent
155: + ": " + n); // NOI18N
156: }
157: }
158: return elements;
159: }
160:
161: /**
162: * Finds AuxiliaryConfiguration for the given project helper. The method
163: * finds project associated with the helper and searches
164: * AuxiliaryConfiguration in project's lookup.
165: *
166: * @param helper instance of project's RakeProjectHelper
167: * @return project's AuxiliaryConfiguration
168: */
169: public static AuxiliaryConfiguration getAuxiliaryConfiguration(
170: RakeProjectHelper helper) {
171: try {
172: Project p = ProjectManager.getDefault().findProject(
173: helper.getProjectDirectory());
174: AuxiliaryConfiguration aux = p.getLookup().lookup(
175: AuxiliaryConfiguration.class);
176: assert aux != null;
177: return aux;
178: } catch (IOException e) {
179: ErrorManager.getDefault().notify(e);
180: return null;
181: }
182: }
183:
184: // /**
185: // * Relativize given file against the original project and if needed use
186: // * ${project.dir} property as base. If file cannot be relativized
187: // * the absolute filepath is returned.
188: // * @param projectBase original project base folder
189: // * @param freeformBase Freeform project base folder
190: // * @param location location to relativize
191: // * @return text suitable for storage in project.xml representing given location
192: // */
193: // public static String relativizeLocation(File projectBase, File freeformBase, File location) {
194: // if (CollocationQuery.areCollocated(projectBase, location)) {
195: // if (projectBase.equals(freeformBase)) {
196: // return PropertyUtils.relativizeFile(projectBase, location);
197: // } else if (projectBase.equals(location) && ProjectConstants.PROJECT_LOCATION_PREFIX.endsWith("/")) { // NOI18N
198: // return ProjectConstants.PROJECT_LOCATION_PREFIX.substring(0, ProjectConstants.PROJECT_LOCATION_PREFIX.length() - 1);
199: // } else {
200: // return ProjectConstants.PROJECT_LOCATION_PREFIX + PropertyUtils.relativizeFile(projectBase, location);
201: // }
202: // } else {
203: // return location.getAbsolutePath();
204: // }
205: // }
206:
207: /**
208: * Resolve given string value (e.g. "${project.dir}/lib/lib1.jar")
209: * to a File.
210: * @param evaluator evaluator to use for properties resolving
211: * @param freeformProjectBase freeform project base folder
212: * @param val string to be resolved as file
213: * @return resolved File or null if file could not be resolved
214: */
215: public static File resolveFile(PropertyEvaluator evaluator,
216: File freeformProjectBase, String val) {
217: String location = evaluator.evaluate(val);
218: if (location == null) {
219: return null;
220: }
221: return PropertyUtils.resolveFile(freeformProjectBase, location);
222: }
223:
224: // /**
225: // * Returns location of original project base folder. The location can be dirrerent
226: // * from NetBeans metadata project folder.
227: // * @param helper RakeProjectHelper associated with the project
228: // * @param evaluator PropertyEvaluator associated with the project
229: // * @return location of original project base folder
230: // */
231: // public static File getProjectLocation(RakeProjectHelper helper, PropertyEvaluator evaluator) {
232: // //assert ProjectManager.mutex().isReadAccess() || ProjectManager.mutex().isWriteAccess();
233: // String loc = evaluator.getProperty(ProjectConstants.PROP_PROJECT_LOCATION);
234: // if (loc != null) {
235: // return helper.resolveFile(loc);
236: // } else {
237: // return FileUtil.toFile(helper.getProjectDirectory());
238: // }
239: // }
240:
241: /**
242: * Append child element to the correct position according to given
243: * order.
244: * @param parent parent to which the child will be added
245: * @param el element to be added
246: * @param order order of the elements which must be followed
247: */
248: public static void appendChildElement(Element parent, Element el,
249: String[] order) {
250: Element insertBefore = null;
251: List l = Arrays.asList(order);
252: int index = l.indexOf(el.getLocalName());
253: assert index != -1 : el.getLocalName() + " was not found in "
254: + l; // NOI18N
255: Iterator it = Util.findSubElements(parent).iterator();
256: while (it.hasNext()) {
257: Element e = (Element) it.next();
258: int index2 = l.indexOf(e.getLocalName());
259: assert index2 != -1 : e.getLocalName()
260: + " was not found in " + l; // NOI18N
261: if (index2 > index) {
262: insertBefore = e;
263: break;
264: }
265: }
266: parent.insertBefore(el, insertBefore);
267: }
268:
269: // /**Get the "default" (user-specified) ant script for the given freeform project.
270: // * Please note that this method may return <code>null</code> if there is no such script.
271: // *
272: // * WARNING: This method is there only for a limited set of usecases like the profiler plugin.
273: // * It should not be used by the freeform project natures.
274: // *
275: // * @param prj the freeform project
276: // * @return the "default" ant script or <code>null</code> if there is no such a script
277: // * @throws IllegalArgumentException if the passed project is not a freeform project.
278: // */
279: // public static FileObject getDefaultAntScript(Project prj) throws IllegalArgumentException {
280: // ProjectAccessor accessor = prj.getLookup().lookup(ProjectAccessor.class);
281: //
282: // if (accessor == null) {
283: // throw new IllegalArgumentException("Only FreeformProjects are supported.");
284: // }
285: //
286: // return FreeformProjectGenerator.getAntScript(accessor.getHelper(), accessor.getEvaluator());
287: // }
288:
289: public static void preselectWizardPlatform(final JComboBox platforms) {
290: org.netbeans.modules.ruby.platform.Util.preselectPlatform(
291: platforms, LAST_PLATFORM_ID);
292: }
293:
294: public static void storeWizardPlatform(JComboBox platforms) {
295: org.netbeans.modules.ruby.platform.Util.getPreferences()
296: .put(
297: LAST_PLATFORM_ID,
298: PlatformComponentFactory.getPlatform(platforms)
299: .getID());
300: }
301: }
|