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.codegen.model;
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.ArrayList;
048: import java.util.Collections;
049: import java.util.HashMap;
050: import java.util.List;
051: import java.util.Map;
052: import java.util.SortedMap;
053: import java.util.TreeMap;
054: import javax.lang.model.element.AnnotationMirror;
055: import javax.xml.parsers.DocumentBuilder;
056: import javax.xml.parsers.DocumentBuilderFactory;
057: import javax.xml.parsers.ParserConfigurationException;
058: import javax.xml.xpath.XPathExpressionException;
059: import org.netbeans.api.project.Project;
060: import org.netbeans.api.java.source.JavaSource;
061: import org.netbeans.modules.websvc.rest.RestUtils;
062: import org.netbeans.modules.websvc.rest.codegen.Constants;
063: import org.netbeans.modules.websvc.rest.model.api.RestConstants;
064: import org.netbeans.modules.websvc.rest.support.JavaSourceHelper;
065: import org.openide.filesystems.FileObject;
066: import org.openide.util.Exceptions;
067: import org.w3c.dom.Attr;
068: import org.w3c.dom.Document;
069: import org.w3c.dom.NamedNodeMap;
070: import org.w3c.dom.Node;
071: import org.w3c.dom.NodeList;
072: import org.xml.sax.SAXException;
073:
074: /**
075: * ClientStubModel
076: *
077: * @author Ayub Khan
078: */
079: public class ClientStubModel {
080:
081: private Project p;
082:
083: private SortedMap<String, JavaSource> srcMap = new TreeMap<String, JavaSource>();
084:
085: private List<Resource> resourceList = Collections.emptyList();
086:
087: private Map<String, RepresentationDocument> documentMap = new HashMap<String, RepresentationDocument>();
088: private FileObject wadlFile;
089:
090: public ClientStubModel() {
091: }
092:
093: public List<Resource> getResources() {
094: return resourceList;
095: }
096:
097: public void addResource(Resource m) {
098: resourceList.add(m);
099: }
100:
101: public JavaSource getJavaSource(String className) {
102: return srcMap.get(className);
103: }
104:
105: public void buildModel(Project p) throws IOException {
106: this .p = p;
107: this .resourceList = new ArrayList<Resource>();
108: List<JavaSource> sources = JavaSourceHelper.getJavaSources(p);
109: List<JavaSource> staticR = new ArrayList<JavaSource>();
110: List<JavaSource> dynamicR = new ArrayList<JavaSource>();
111: List<JavaSource> converters = new ArrayList<JavaSource>();
112: for (JavaSource src : sources) {
113: if (JavaSourceHelper.isEntity(src)) {
114: continue;
115: }
116: String className = JavaSourceHelper
117: .getClassNameQuietly(src);
118: srcMap.put(className, src);
119: if (RestUtils.isStaticResource(src)) {
120: staticR.add(src);
121: } else if (RestUtils.isConverter(src)) {
122: converters.add(src);
123: } else if (RestUtils.isDynamicResource(src)) {
124: dynamicR.add(src);
125: }
126: }
127: for (JavaSource rSrc : staticR) {
128: Resource r = createResource(rSrc);
129: addResource(r);
130: }
131: for (JavaSource rSrc : dynamicR) {
132: Resource r = createResource(rSrc);
133: addResource(r);
134: }
135: }
136:
137: public String buildModel(FileObject wadlFile) throws IOException {
138: String appName = null;
139: this .wadlFile = wadlFile;
140: this .resourceList = new ArrayList<Resource>();
141: List<JavaSource> staticR = new ArrayList<JavaSource>();
142: List<JavaSource> dynamicR = new ArrayList<JavaSource>();
143: List<JavaSource> converters = new ArrayList<JavaSource>();
144: try {
145: DocumentBuilderFactory dbf = DocumentBuilderFactory
146: .newInstance();
147: DocumentBuilder db = dbf.newDocumentBuilder();
148: Document doc = db.parse(wadlFile.getInputStream());
149:
150: //App base
151: appName = RestUtils.getAttributeValue(doc,
152: "//application/resources", "base");
153: appName = appName.replaceAll("http://", "");
154: if (appName.endsWith("/"))
155: appName = appName.substring(0, appName.length() - 1);
156: appName = appName.replaceAll("/", "_");
157: appName = appName.replaceAll(":", "_");
158:
159: //Resource
160: NodeList resourceNodes = RestUtils.getNodeList(doc,
161: "//application/resources/resource");
162: if (resourceNodes != null && resourceNodes.getLength() > 0) {
163: for (int i = 0; i < resourceNodes.getLength(); i++) {
164: Node resource = resourceNodes.item(i);
165: NamedNodeMap rAttrList = resource.getAttributes();
166: String path = null;
167: Attr pathAttr = (Attr) rAttrList
168: .getNamedItem("path");
169: if (pathAttr != null) {
170: path = pathAttr.getNodeValue();
171: }
172: String name = path.replaceAll("/", "");
173: name = name.substring(0, 1).toUpperCase()
174: + name.substring(1);
175: Resource r = new Resource(name, path);
176: //Methods
177: NodeList methods = RestUtils.getNodeList(resource,
178: "method");
179: if (methods != null && methods.getLength() > 0) {
180: for (int j = 0; j < methods.getLength(); j++) {
181: Node method = methods.item(j);
182: NamedNodeMap mAttrList = method
183: .getAttributes();
184: String mName = null;
185: Attr nameAttr = (Attr) mAttrList
186: .getNamedItem("name");
187: if (nameAttr != null) {
188: mName = nameAttr.getNodeValue();
189: }
190: if (mName != null) {
191: Method m = new Method(mName
192: .toLowerCase());
193: m.setType(MethodType.valueOf(mName));
194: NodeList requests = RestUtils
195: .getNodeList(method, "request");
196: if (requests != null
197: && requests.getLength() > 0) {
198: Node request = requests.item(0);
199: Request req = new Request();
200: NodeList reps = RestUtils
201: .getNodeList(request,
202: "representation");
203: if (reps != null
204: && reps.getLength() > 0) {
205: for (int l = 0; l < reps
206: .getLength(); l++) {
207: Node rep = reps.item(l);
208: String media = "application/xml";
209: Attr mediaAttr = (Attr) rep
210: .getAttributes()
211: .getNamedItem(
212: "mediaType");
213: if (mediaAttr != null) {
214: media = mediaAttr
215: .getNodeValue();
216: }
217: Representation rep1 = new Representation(
218: media);
219: req.addRepresentation(rep1);
220: }
221: }
222: m.setRequest(req);
223: }
224: NodeList responses = RestUtils
225: .getNodeList(method, "response");
226: if (responses != null
227: && responses.getLength() > 0) {
228: Node request = responses.item(0);
229: Response res = new Response();
230: NodeList ress = RestUtils
231: .getNodeList(request,
232: "representation");
233: if (ress != null
234: && ress.getLength() > 0) {
235: for (int l = 0; l < ress
236: .getLength(); l++) {
237: Node rep = ress.item(l);
238: String media = "application/xml";
239: Attr mediaAttr = (Attr) rep
240: .getAttributes()
241: .getNamedItem(
242: "mediaType");
243: if (mediaAttr != null) {
244: media = mediaAttr
245: .getNodeValue();
246: }
247: Representation rep1 = new Representation(
248: media);
249: res.addRepresentation(rep1);
250: }
251: }
252: m.setResponse(res);
253: }
254: r.addMethod(m);
255: }
256: }
257: }
258: addResource(r);
259: }
260: }
261: } catch (XPathExpressionException ex) {
262: Exceptions.printStackTrace(ex);
263: } catch (SAXException ex) {
264: Exceptions.printStackTrace(ex);
265: } catch (ParserConfigurationException ex) {
266: Exceptions.printStackTrace(ex);
267: }
268: return appName;
269: }
270:
271: private Resource createResource(JavaSource rSrc) throws IOException {
272: String name = null;
273: String path = null;
274: String template = RestUtils.findUri(rSrc);
275: if (template != null) {
276: path = template;
277: name = path;
278: if (name.startsWith("/"))
279: name = name.substring(1);
280: if (name.endsWith("/"))
281: name = name.substring(0, name.length() - 1);
282: name = name.substring(0, 1).toUpperCase()
283: + name.substring(1);
284: } else {
285: String className = JavaSourceHelper
286: .getClassNameQuietly(rSrc);
287: name = RestUtils.findStubNameFromClass(className);
288: path = name.substring(0, 1).toLowerCase()
289: + name.substring(1);
290: }
291: Resource r = new Resource(name, path);
292: buildResource(r, rSrc);
293: return r;
294: }
295:
296: private void buildResource(Resource r, JavaSource src)
297: throws IOException {
298: r.setSource(src);
299: List<MethodTree> trees = JavaSourceHelper.getAllMethods(src);
300: for (MethodTree tree : trees) {
301: String mName = tree.getName().toString();
302: Method m = null;
303: List<? extends AnnotationTree> mAnons = tree.getModifiers()
304: .getAnnotations();
305: if (mAnons != null && mAnons.size() > 0) {
306: for (AnnotationTree mAnon : mAnons) {
307: String mAnonType = mAnon.getAnnotationType()
308: .toString();
309: List<? extends ExpressionTree> eAnons = mAnon
310: .getArguments();
311: if (RestConstants.PATH_ANNOTATION.equals(mAnonType)
312: || RestConstants.PATH.equals(mAnonType)) {
313: m = createNavigationMethod(mName);
314: m.setTree(tree);
315: m.setType(MethodType.GETCHILD);
316: for (ExpressionTree eAnon : eAnons) {
317: String value = eAnon.toString();
318: if (value.contains("{")) {
319: String childRes = tree.getReturnType()
320: .toString();
321: if (childRes.indexOf(".") != -1)
322: childRes = childRes
323: .substring(childRes
324: .lastIndexOf(".") + 1);
325: if (childRes.indexOf("Resource") != -1)
326: childRes = childRes
327: .substring(
328: 0,
329: childRes
330: .indexOf("Resource"));
331: String rName = r.getName();
332: if ((childRes + "s").equals(rName))
333: r.setIsContainer(true);
334: value = value.substring(value
335: .indexOf("{") + 1, value
336: .lastIndexOf("}"));
337: } else if (value.contains("\"")
338: && value.contains("/")) {
339: value = value.substring(value
340: .indexOf("\"") + 1, value
341: .lastIndexOf("/"));
342: } else {
343: throw new IOException(
344: "Cannot find method with "
345: + "@Path(\"subresource/\") or @Path(\"{containerId}/\")");
346: }
347: ((NavigationMethod) m)
348: .setNavigationUri(value);
349: }
350: String returnType = tree.getReturnType()
351: .toString();
352: if (returnType != null) {
353: int ndx = returnType.lastIndexOf(".");
354: if (ndx != -1)
355: returnType = returnType
356: .substring(ndx + 1);
357: }
358: String linkName = RestUtils
359: .findStubNameFromClass(returnType);
360: ((NavigationMethod) m).setLinkName(linkName);
361: } else if (RestConstants.GET_ANNOTATION
362: .equals(mAnonType)
363: || RestConstants.GET.equals(mAnonType)) {
364: if (m == null) {
365: m = createMethod(mName, tree);
366: m.setType(MethodType.GET);
367: }
368: } else if (RestConstants.POST_ANNOTATION
369: .equals(mAnonType)
370: || RestConstants.POST.equals(mAnonType)) {
371: if (m == null) {
372: m = createMethod(mName, tree);
373: m.setType(MethodType.POST);
374: }
375: } else if (RestConstants.PUT_ANNOTATION
376: .equals(mAnonType)
377: || RestConstants.PUT.equals(mAnonType)) {
378: if (m == null) {
379: m = createMethod(mName, tree);
380: m.setType(MethodType.PUT);
381: }
382: } else if (RestConstants.DELETE_ANNOTATION
383: .equals(mAnonType)
384: || RestConstants.DELETE.equals(mAnonType)) {
385: if (m == null) {
386: m = createMethod(mName, tree);
387: m.setType(MethodType.DELETE);
388: }
389: } else if (RestConstants.PRODUCE_MIME_ANNOTATION
390: .equals(mAnonType)
391: || RestConstants.PRODUCE_MIME
392: .equals(mAnonType)) {
393: if (m == null) {
394: m = createMethod(mName, tree);
395: }
396: for (ExpressionTree eAnon : eAnons) {
397: String value = RestUtils
398: .getValueFromAnnotation(eAnon);
399: String[] mimeTypes = value.split(",");
400: for (String mimeType : mimeTypes) {
401: Representation rep = new Representation(
402: mimeType);
403: m.getResponse().addRepresentation(rep);
404: }
405: }
406: } else if (RestConstants.CONSUME_MIME_ANNOTATION
407: .equals(mAnonType)
408: || RestConstants.CONSUME_MIME
409: .equals(mAnonType)) {
410: if (m == null) {
411: m = createMethod(mName, tree);
412: }
413: for (ExpressionTree eAnon : eAnons) {
414: String value = RestUtils
415: .getValueFromAnnotation(eAnon);
416: String[] mimeTypes = value.split(",");
417: for (String mimeType : mimeTypes) {
418: Representation rep = new Representation(
419: mimeType);
420: m.getRequest().addRepresentation(rep);
421: }
422: }
423: }
424: }
425: }
426: if (m != null) {
427: r.addMethod(m);
428: }
429: }
430: buildRepresentationDocument(r, src);
431: }
432:
433: private Method createMethod(String mName, MethodTree tree) {
434: Method m = new Method(mName);
435: Representation rep1 = new Representation("application/xml");
436: Request request = new Request();
437: request.addRepresentation(rep1);
438: m.setRequest(request);
439: Representation rep2 = new Representation("application/xml");
440: Response response = new Response();
441: response.addRepresentation(rep2);
442: m.setResponse(response);
443: m.setTree(tree);
444: return m;
445: }
446:
447: private Method createNavigationMethod(String mName) {
448: Method m = new NavigationMethod(mName);
449: Representation rep1 = new Representation("application/xml");
450: Request request = new Request();
451: request.addRepresentation(rep1);
452: m.setRequest(request);
453: Representation rep2 = new Representation("application/xml");
454: Response response = new Response();
455: response.addRepresentation(rep2);
456: m.setResponse(response);
457: return m;
458: }
459:
460: private void buildRepresentationDocument(Resource r, JavaSource rSrc)
461: throws IOException {
462: RepresentationDocument rDoc = r.getRepresentation();
463: /*
464: * Find a getXml method from resource source rSrc. The return type will be its converter
465: * Eg:
466: * @HttpMethod("GET")
467: * @ProduceMime("application/xml")
468: * public PlaylistsConverter getXml() {}
469: */
470: MethodTree method = RestUtils.findGetAsXmlMethod(rSrc); // getXml() method tree
471: if (method != null) {
472: String converter = method.getReturnType().toString();
473: RepresentationNode rootNode = createRootNode(converter,
474: rDoc);
475: rDoc.setRoot(rootNode);
476: documentMap.put(converter, rDoc);
477: processConverter(converter, rDoc, rootNode, r);
478: }
479: }
480:
481: private RepresentationNode createRootNode(String cName,
482: RepresentationDocument rr) {
483: JavaSource cSrc = getJavaSource(cName);
484: if (cSrc == null)
485: return null;
486: List<? extends AnnotationMirror> annotations = JavaSourceHelper
487: .getClassAnnotations(cSrc);
488: if (annotations == null)
489: return null;
490: for (int i = 0; i < annotations.size(); i++) {
491: AnnotationMirror annotation = annotations.get(i);
492: String cAnonType = annotation.getAnnotationType()
493: .toString();
494: if (Constants.XML_ROOT_ELEMENT_ANNOTATION.equals(cAnonType)
495: || Constants.XML_ROOT_ELEMENT.equals(cAnonType)) {
496: /*
497: * @XmlRootElement(name = "playlists")
498: * public class PlaylistsConverter {}
499: */
500: String rootName = RestUtils
501: .getValueFromAnnotation(annotation); // "playlists"
502: RepresentationNode rootNode = new RepresentationNode(
503: rootName);
504: rootNode.setIsRoot(true);
505: return rootNode;
506: }
507: }
508: return null;
509: }
510:
511: private void processConverter(String converter,
512: RepresentationDocument rr, RepresentationNode rElem,
513: Resource r) {
514: assert converter != null;
515: String cName = converter;
516: if (cName.startsWith("Collection") || cName.startsWith("List")
517: || cName.startsWith("Set")) {
518: if (cName.indexOf("<") != -1)
519: cName = cName.substring(cName.indexOf("<") + 1, cName
520: .indexOf(">"));
521: }
522: JavaSource cSrc = getJavaSource(cName);
523: if (cSrc == null)
524: return;
525: List<? extends AnnotationMirror> annotations = JavaSourceHelper
526: .getClassAnnotations(cSrc);
527: if (annotations == null)
528: return;
529: for (int i = 0; i < annotations.size(); i++) {
530: AnnotationMirror annotation = annotations.get(i);
531: String cAnonType = annotation.getAnnotationType()
532: .toString();
533: if (Constants.XML_ROOT_ELEMENT_ANNOTATION.equals(cAnonType)
534: || Constants.XML_ROOT_ELEMENT.equals(cAnonType)) {
535: rElem.setSource(cSrc);
536: List<MethodTree> cTrees = JavaSourceHelper
537: .getAllMethods(cSrc);
538: if (cTrees == null)
539: continue;
540: List<RepresentationNode> elems = new ArrayList<RepresentationNode>();
541: List<String> rTypes = new ArrayList<String>();
542: for (int j = 0; j < cTrees.size(); j++) {
543: MethodTree tree = cTrees.get(j);
544: String mName = tree.getName().toString();
545: List<? extends AnnotationTree> mAnons = tree
546: .getModifiers().getAnnotations();
547: if (mAnons == null)
548: continue;
549:
550: for (int k = 0; k < mAnons.size(); k++) {
551: AnnotationTree mAnon = mAnons.get(k);
552: String mAnonType = mAnon.getAnnotationType()
553: .toString();
554: if (Constants.XML_ELEMENT_ANNOTATION
555: .equals(mAnonType)
556: || Constants.XML_ELEMENT
557: .equals(mAnonType)) {
558: /*
559: * @XmlElement(name = "playlistRef")
560: * public Collection<PlaylistRefConverter> getReferences() {}
561: */
562: String c = tree.getReturnType().toString();
563: RepresentationDocument cDoc = documentMap
564: .get(c);
565: RepresentationNode cElem = null;
566: if (cDoc == null || cDoc.getRoot() == null) {
567: String eName = RestUtils
568: .findElementName(tree, r); // "playlistRef"
569: cElem = new RepresentationNode(eName);
570: cElem.setLink(tree); //getReferences() method tree for tracking the link
571: elems.add(cElem);//process later
572: rTypes.add(c);//process later
573: } else {
574: cElem = cDoc.getRoot();
575: }
576: rElem.addChild(cElem);
577: } else if (Constants.XML_ATTRIBUTE_ANNOTATION
578: .equals(mAnonType)
579: || Constants.XML_ATTRIBUTE
580: .equals(mAnonType)) {
581: /*
582: * @XmlAttribute
583: * public URI getUri() {}
584: */
585: String attrName = RestUtils
586: .findElementName(tree, r); // "uri"
587: RepresentationNode attr = new RepresentationNode(
588: attrName);
589: attr.setLink(tree);
590: rElem.addAttribute(attr);
591: }
592: }
593: }
594:
595: //now process element methods
596: for (int j = 0; j < elems.size(); j++) {
597: processConverter(rTypes.get(j), rr, elems.get(j), r);
598: }
599: }
600: }
601: }
602:
603: public class Resource {
604:
605: private String name;
606: private String path;
607: private String desc;
608:
609: private JavaSource src;
610: private RepresentationDocument rep;
611: private boolean isContainer;
612: private boolean isContainerItem;
613:
614: private List<Method> methodList = Collections.emptyList();
615:
616: public Resource(String name, String path, String desc) {
617: this .name = name;
618: this .path = path;
619: this .desc = desc;
620: this .methodList = new ArrayList<Method>();
621: this .rep = new RepresentationDocument();
622: }
623:
624: public Resource(String name, String path) {
625: this (name, path, name);
626: }
627:
628: public String getName() {
629: return name;
630: }
631:
632: public String getPath() {
633: return path;
634: }
635:
636: public String getDescription() {
637: return desc;
638: }
639:
640: public void setDescription(String desc) {
641: this .desc = desc;
642: }
643:
644: public List<Method> getMethods() {
645: return methodList;
646: }
647:
648: public void addMethod(Method m) {
649: methodList.add(m);
650: }
651:
652: protected JavaSource getSource() {
653: return this .src;
654: }
655:
656: protected void setSource(JavaSource src) {
657: this .src = src;
658: }
659:
660: public RepresentationDocument getRepresentation() {
661: return rep;
662: }
663:
664: public boolean isContainer() {
665: return isContainer;
666: }
667:
668: public void setIsContainer(boolean isContainer) {
669: this .isContainer = isContainer;
670: }
671:
672: public boolean isContainerItem() {
673: //TODO
674: // return this.isContainerItem;
675: return !this .isContainer;
676: }
677:
678: public void setIsContainerItem(boolean isContainerItem) {
679: this .isContainerItem = isContainerItem;
680: }
681:
682: @Override
683: public String toString() {
684: return getName() + " : " + getPath();
685: }
686: }
687:
688: /*
689: * Represents JAXB document
690: */
691: public class RepresentationDocument {
692:
693: private RepresentationNode root;
694:
695: public RepresentationDocument() {
696: }
697:
698: public RepresentationNode getRoot() {
699: return root;
700: }
701:
702: protected void setRoot(RepresentationNode root) {
703: this .root = root;
704: }
705: }
706:
707: /*
708: * Represents JAXB node
709: */
710: public class RepresentationNode {
711:
712: private String name;
713:
714: private MethodTree link;
715: private JavaSource src;
716:
717: private List<RepresentationNode> attrList = new ArrayList<RepresentationNode>();
718: private List<RepresentationNode> childList = new ArrayList<RepresentationNode>();
719: private boolean isRoot;
720:
721: public RepresentationNode(String name) {
722: this .name = name;
723: }
724:
725: public String getName() {
726: return name;
727: }
728:
729: public MethodTree getLink() {
730: return link;
731: }
732:
733: protected void setLink(MethodTree link) {
734: this .link = link;
735: }
736:
737: public List<RepresentationNode> getAttributes() {
738: return attrList;
739: }
740:
741: public void addAttribute(RepresentationNode m) {
742: attrList.add(m);
743: }
744:
745: public List<RepresentationNode> getChildren() {
746: return childList;
747: }
748:
749: public void addChild(RepresentationNode m) {
750: childList.add(m);
751: }
752:
753: public boolean isRoot() {
754: return isRoot;
755: }
756:
757: protected void setIsRoot(boolean isRoot) {
758: this .isRoot = isRoot;
759: }
760:
761: public boolean isReference() {
762: return getName() != null && getName().endsWith("Ref");
763: }
764:
765: public boolean isEntity() {
766: return this .src != null;
767: }
768:
769: protected JavaSource getSource() {
770: return this .src;
771: }
772:
773: protected void setSource(JavaSource src) {
774: this .src = src;
775: }
776:
777: @Override
778: public String toString() {
779: return getName();
780: }
781: }
782:
783: public enum MethodType {
784:
785: GET(Constants.HttpMethodType.GET.value()) //NOI18N
786: , PUT(Constants.HttpMethodType.PUT.value()) //NOI18N
787: , POST(Constants.HttpMethodType.POST.value()) //NOI18N
788: , DELETE(Constants.HttpMethodType.DELETE.value()) //NOI18N
789: , GETCHILD("getChild");
790: //NOI18N
791: private String prefix;
792:
793: MethodType(String prefix) {
794: this .prefix = prefix;
795: }
796:
797: public String value() {
798: return name();
799: }
800:
801: public String prefix() {
802: return prefix;
803: }
804:
805: private static MethodType NAVIGATE;
806: }
807:
808: public class Method {
809:
810: private String name;
811: private MethodType type;
812: private Request request;
813: private Response response;
814:
815: private MethodTree tree;
816:
817: public Method(String name) {
818: this .name = name;
819: }
820:
821: public String getName() {
822: return name;
823: }
824:
825: public MethodType getType() {
826: return type;
827: }
828:
829: protected void setType(MethodType type) {
830: this .type = type;
831: }
832:
833: public Request getRequest() {
834: return request;
835: }
836:
837: protected void setRequest(Request r) {
838: this .request = r;
839: }
840:
841: public Response getResponse() {
842: return response;
843: }
844:
845: public void setResponse(Response r) {
846: this .response = r;
847: }
848:
849: protected MethodTree getTree() {
850: return tree;
851: }
852:
853: protected void setTree(MethodTree tree) {
854: this .tree = tree;
855: }
856: }
857:
858: public class NavigationMethod extends Method {
859:
860: private String nUri; //uri to get child stub eg: 'playlistId'
861: private String linkName; //child stub name eg: 'Playlist'
862:
863: public NavigationMethod(String name) {
864: super (name);
865: }
866:
867: public String getNavigationUri() {
868: return nUri;
869: }
870:
871: protected void setNavigationUri(String nUri) {
872: this .nUri = nUri;
873: }
874:
875: public String getLinkName() {
876: return linkName;
877: }
878:
879: protected void setLinkName(String linkName) {
880: this .linkName = linkName;
881: }
882: }
883:
884: public class Request {
885:
886: private List<Representation> repList = new ArrayList<Representation>();
887:
888: public Request() {
889: }
890:
891: public List<Representation> getRepresentation() {
892: return repList;
893: }
894:
895: protected void addRepresentation(Representation rep) {
896: this .repList.add(rep);
897: }
898:
899: protected void setRepresentation(List<Representation> repList) {
900: this .repList = repList;
901: }
902: }
903:
904: public class Response {
905:
906: private List<Representation> repList = new ArrayList<Representation>();
907:
908: public Response() {
909: }
910:
911: public List<Representation> getRepresentation() {
912: return repList;
913: }
914:
915: protected void addRepresentation(Representation rep) {
916: this .repList.add(rep);
917: }
918:
919: protected void setRepresentation(List<Representation> repList) {
920: this .repList = repList;
921: }
922: }
923:
924: public class Representation {
925:
926: private String mime;
927:
928: public Representation(String mime) {
929: this .mime = mime;
930: }
931:
932: public String getMime() {
933: return mime;
934: }
935: }
936: }
|