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-2007 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.websvc.rest;
042:
043: import com.sun.source.tree.AnnotationTree;
044: import com.sun.source.tree.ExpressionTree;
045: import com.sun.source.tree.MethodTree;
046: import java.io.IOException;
047: import java.util.List;
048: import javax.lang.model.element.AnnotationMirror;
049: import org.netbeans.api.java.source.JavaSource;
050: import org.netbeans.api.project.FileOwnerQuery;
051: import org.netbeans.api.project.Project;
052: import org.netbeans.modules.websvc.rest.spi.RestSupport;
053: import org.netbeans.modules.websvc.rest.support.JavaSourceHelper;
054: import org.openide.filesystems.FileObject;
055: import javax.xml.xpath.*;
056: import org.netbeans.modules.websvc.rest.codegen.Constants;
057: import org.netbeans.modules.websvc.rest.codegen.model.ClientStubModel;
058: import org.netbeans.modules.websvc.rest.model.api.RestConstants;
059: import org.netbeans.modules.websvc.rest.model.api.RestServicesModel;
060: import org.openide.filesystems.FileSystem;
061: import org.openide.filesystems.Repository;
062: import org.openide.loaders.DataFolder;
063: import org.openide.loaders.DataObject;
064: import org.w3c.dom.Document;
065: import org.w3c.dom.Node;
066: import org.w3c.dom.NodeList;
067:
068: /**
069: * REST support utilitities across all project types.
070: *
071: * @author Nam Nguyen
072: */
073: public class RestUtils {
074:
075: /**
076: * Makes sure project is ready for REST development.
077: * @param source source file or directory as part of REST application project.
078: */
079: public static void ensureRestDevelopmentReady(FileObject source)
080: throws IOException {
081: Project p = FileOwnerQuery.getOwner(source);
082: if (p != null) {
083: ensureRestDevelopmentReady(p);
084: }
085: }
086:
087: /**
088: * Makes sure project is ready for REST development.
089: * @param project project to make REST development ready
090: */
091: public static void ensureRestDevelopmentReady(Project project)
092: throws IOException {
093: RestSupport restSupport = project.getLookup().lookup(
094: RestSupport.class);
095: if (restSupport != null) {
096: restSupport.ensureRestDevelopmentReady();
097: }
098: }
099:
100: /**
101: * Makes sure project is ready for REST development.
102: * @param project project to make REST development ready
103: */
104: public static void removeRestDevelopmentReadiness(Project project)
105: throws IOException {
106: RestSupport restSupport = project.getLookup().lookup(
107: RestSupport.class);
108: if (restSupport != null && restSupport.isRestSupportOn()) {
109: restSupport.removeRestDevelopmentReadiness();
110: }
111: }
112:
113: /**
114: * Returns true if the project supports REST framework.
115: * @param project project to make REST development ready
116: */
117: public static boolean supportsRestDevelopment(Project project) {
118: RestSupport restSupport = project.getLookup().lookup(
119: RestSupport.class);
120: return restSupport != null;
121: }
122:
123: public static boolean isRestEnabled(Project project) {
124: RestSupport restSupport = project.getLookup().lookup(
125: RestSupport.class);
126: return restSupport != null && restSupport.isRestSupportOn();
127: }
128:
129: public static void setRestEnabled(Project project, Boolean v) {
130: RestSupport restSupport = project.getLookup().lookup(
131: RestSupport.class);
132: if (restSupport != null) {
133: restSupport.setRestSupport(v);
134: }
135: }
136:
137: public static RestSupport getRestSupport(Project project) {
138: return project.getLookup().lookup(RestSupport.class);
139: }
140:
141: public static RestServicesModel getRestServicesMetadataModel(
142: Project project) {
143: RestSupport support = getRestSupport(project);
144: if (support != null) {
145: return support.getRestServicesModel();
146: }
147: return null;
148: }
149:
150: public static void disableRestServicesChangeListner(Project project) {
151: final RestServicesModel wsModel = RestUtils
152: .getRestServicesMetadataModel(project);
153: if (wsModel == null) {
154: return;
155: }
156: wsModel.disablePropertyChangeListener();
157: }
158:
159: public static void enableRestServicesChangeListner(Project project) {
160: final RestServicesModel wsModel = RestUtils
161: .getRestServicesMetadataModel(project);
162: if (wsModel == null) {
163: return;
164: }
165: wsModel.enablePropertyChangeListener();
166: }
167:
168: //
169: // TODO: The following methods don't belong here. Some of them should go into
170: // JavaSourceHelper and the XML/DOM related methods should go into
171: // their own utility class.
172: //
173: public static String getAttributeValue(Node n, String nodePath,
174: String attrName) throws XPathExpressionException {
175: String attrValue = null;
176: XPathFactory factory = XPathFactory.newInstance();
177: XPath xpath = factory.newXPath();
178: XPathExpression expr3 = xpath.compile(nodePath + "/@"
179: + attrName);
180: Object result3 = expr3.evaluate(n, XPathConstants.NODESET);
181: NodeList nodes3 = (NodeList) result3;
182: for (int i = 0; i < nodes3.getLength(); i++) {
183: attrValue = nodes3.item(i).getNodeValue();
184: break;
185: }
186: return attrValue;
187: }
188:
189: public static NodeList getNodeList(Node n, String nodePath)
190: throws XPathExpressionException {
191: String attrValue = null;
192: XPathFactory factory = XPathFactory.newInstance();
193: XPath xpath = factory.newXPath();
194: XPathExpression expr3 = xpath.compile(nodePath);
195: Object result3 = expr3.evaluate(n, XPathConstants.NODESET);
196: NodeList nodes3 = (NodeList) result3;
197: return nodes3;
198: }
199:
200: public static FileObject findWadlFile(Project p) {
201: FileObject pf = p.getProjectDirectory();
202: FileObject f = pf
203: .getFileObject("/build/web/WEB-INF/classes/com/sun/ws/rest/wadl/resource/application.wadl");
204: return f;
205: }
206:
207: public static DataObject createDataObjectFromTemplate(
208: String template, FileObject targetFolder, String targetName)
209: throws IOException {
210: assert template != null;
211: assert targetFolder != null;
212: assert targetName != null && targetName.trim().length() > 0;
213:
214: FileSystem defaultFS = Repository.getDefault()
215: .getDefaultFileSystem();
216: FileObject templateFO = defaultFS.findResource(template);
217: DataObject templateDO = DataObject.find(templateFO);
218: DataFolder dataFolder = DataFolder.findFolder(targetFolder);
219:
220: return templateDO.createFromTemplate(dataFolder, targetName);
221: }
222:
223: public static String findStubNameFromClass(String className) {
224: String name = className;
225: int index = name.lastIndexOf("Resource");
226: if (index != -1) {
227: name = name.substring(0, index);
228: } else {
229: index = name.lastIndexOf("Converter");
230: if (index != -1)
231: name = name.substring(0, index);
232: }
233: return name;
234: }
235:
236: public static String findUri(JavaSource rSrc) {
237: String path = null;
238: List<? extends AnnotationMirror> annotations = JavaSourceHelper
239: .getClassAnnotations(rSrc);
240: for (AnnotationMirror annotation : annotations) {
241: String cAnonType = annotation.getAnnotationType()
242: .toString();
243: if (RestConstants.PATH.equals(cAnonType)
244: || RestConstants.PATH_ANNOTATION.equals(cAnonType)) {
245: path = getValueFromAnnotation(annotation);
246: }
247: }
248: return path;
249: }
250:
251: public static boolean isStaticResource(JavaSource src) {
252: List<? extends AnnotationMirror> annotations = JavaSourceHelper
253: .getClassAnnotations(src);
254: if (annotations != null && annotations.size() > 0) {
255: for (AnnotationMirror annotation : annotations) {
256: String classAnonType = annotation.getAnnotationType()
257: .toString();
258: if (RestConstants.PATH.equals(classAnonType)) {
259: return true;
260: } else {
261: return false;
262: }
263: }
264: }
265: return false;
266: }
267:
268: public static boolean isConverter(JavaSource src) {
269: List<? extends AnnotationMirror> annotations = JavaSourceHelper
270: .getClassAnnotations(src);
271: if (annotations != null && annotations.size() > 0) {
272: for (AnnotationMirror annotation : annotations) {
273: String classAnonType = annotation.getAnnotationType()
274: .toString();
275: if (Constants.XML_ROOT_ELEMENT.equals(classAnonType)) {
276: return true;
277: }
278: }
279: }
280: return false;
281: }
282:
283: public static boolean isDynamicResource(JavaSource src) {
284: List<MethodTree> trees = JavaSourceHelper.getAllMethods(src);
285: for (MethodTree tree : trees) {
286: List<? extends AnnotationTree> mAnons = tree.getModifiers()
287: .getAnnotations();
288: if (mAnons != null && mAnons.size() > 0) {
289: for (AnnotationTree mAnon : mAnons) {
290: String mAnonType = mAnon.getAnnotationType()
291: .toString();
292: if (RestConstants.PATH_ANNOTATION.equals(mAnonType)
293: || RestConstants.PATH.equals(mAnonType)) {
294: return true;
295: } else if (RestConstants.GET_ANNOTATION
296: .equals(mAnonType)
297: || RestConstants.GET.equals(mAnonType)) {
298: return true;
299: }
300: }
301: }
302: }
303: return false;
304: }
305:
306: public static String findElementName(MethodTree tree,
307: ClientStubModel.Resource r) {
308: String eName = "";
309: List<? extends AnnotationTree> mAnons = tree.getModifiers()
310: .getAnnotations();
311: if (mAnons != null && mAnons.size() > 0) {
312: for (AnnotationTree mAnon : mAnons) {
313: eName = mAnon.toString();
314: if (eName.indexOf("\"") != -1) {
315: eName = getValueFromAnnotation(mAnon);
316: } else {
317: eName = getNameFromMethod(tree);
318: }
319: }
320: }
321: return eName.substring(0, 1).toLowerCase() + eName.substring(1);
322: }
323:
324: public static MethodTree findGetAsXmlMethod(JavaSource rSrc) {
325: MethodTree method = null;
326: List<MethodTree> rTrees = JavaSourceHelper.getAllMethods(rSrc);
327: for (MethodTree tree : rTrees) {
328: String mName = tree.getName().toString();
329: ClientStubModel.Method m = null;
330: boolean isHttpGetMethod = false;
331: boolean isXmlMime = false;
332: List<? extends AnnotationTree> mAnons = tree.getModifiers()
333: .getAnnotations();
334: if (mAnons != null && mAnons.size() > 0) {
335: for (AnnotationTree mAnon : mAnons) {
336: String mAnonType = mAnon.getAnnotationType()
337: .toString();
338: if (RestConstants.GET_ANNOTATION.equals(mAnonType)
339: || RestConstants.GET.equals(mAnonType)) {
340: isHttpGetMethod = true;
341: } else if (RestConstants.PRODUCE_MIME_ANNOTATION
342: .equals(mAnonType)
343: || RestConstants.PRODUCE_MIME
344: .equals(mAnonType)) {
345: isXmlMime = true;
346: }
347: }
348: if (isHttpGetMethod && isXmlMime) {
349: method = tree;
350: break;
351: }
352: }
353: }
354: return method;
355: }
356:
357: public static String getNameFromMethod(MethodTree tree) {
358: String attrName = tree.getName().toString();
359: attrName = attrName.substring(attrName.indexOf("get") + 3);
360: attrName = attrName.substring(0, 1).toLowerCase()
361: + attrName.substring(1);
362: return attrName;
363: }
364:
365: public static String getValueFromAnnotation(
366: AnnotationMirror annotation) {
367: return getValueFromAnnotation(annotation.getElementValues()
368: .values().toString());
369: }
370:
371: public static String getValueFromAnnotation(AnnotationTree mAnon) {
372: return getValueFromAnnotation(mAnon.toString());
373: }
374:
375: public static String getValueFromAnnotation(ExpressionTree eAnon) {
376: return getValueFromAnnotation(eAnon.toString());
377: }
378:
379: public static String getValueFromAnnotation(String value) {
380: if (value.indexOf("\"") != -1)
381: value = value.substring(value.indexOf("\"") + 1, value
382: .lastIndexOf("\""));
383: return value;
384: }
385:
386: public static String createGetterMethodName(
387: ClientStubModel.RepresentationNode n) {
388: String mName = "get";
389: if (n.getLink() != null)
390: mName = escapeJSReserved(n.getLink().getName().toString());
391: else {
392: mName = n.getName();
393: mName = "get" + mName.substring(0, 1).toUpperCase()
394: + mName.substring(1);
395: }
396: return mName;
397: }
398:
399: public static String escapeJSReserved(String key) {
400: if (key.equals("delete"))
401: return key + "_";
402: else
403: return key;
404: }
405: }
|