0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.websvc.rest.codegen;
0043:
0044: import com.sun.source.tree.ClassTree;
0045: import com.sun.source.tree.Tree;
0046: import java.io.File;
0047: import java.io.IOException;
0048: import java.util.ArrayList;
0049: import java.util.Arrays;
0050: import java.util.Collection;
0051: import java.util.HashMap;
0052: import java.util.HashSet;
0053: import java.util.List;
0054: import java.util.Map;
0055: import java.util.Set;
0056: import javax.lang.model.element.Modifier;
0057: import org.netbeans.api.java.source.JavaSource;
0058: import org.netbeans.api.java.source.ModificationResult;
0059: import org.netbeans.api.java.source.WorkingCopy;
0060: import org.netbeans.api.progress.ProgressHandle;
0061: import org.netbeans.modules.websvc.rest.codegen.Constants.HttpMethodType;
0062: import org.netbeans.modules.websvc.rest.codegen.Constants.MimeType;
0063: import org.netbeans.modules.websvc.rest.codegen.model.EntityResourceBean;
0064: import org.netbeans.modules.websvc.rest.support.AbstractTask;
0065: import org.netbeans.modules.websvc.rest.codegen.model.EntityClassInfo.FieldInfo;
0066: import org.netbeans.modules.websvc.rest.codegen.model.GenericResourceBean;
0067: import org.netbeans.modules.websvc.rest.codegen.model.RelatedEntityResource;
0068: import org.netbeans.modules.websvc.rest.codegen.model.EntityResourceBeanModel;
0069: import org.netbeans.modules.websvc.rest.model.api.RestConstants;
0070: import org.netbeans.modules.websvc.rest.support.Inflector;
0071: import org.netbeans.modules.websvc.rest.support.JavaSourceHelper;
0072: import org.netbeans.modules.websvc.rest.support.Utils;
0073: import org.netbeans.modules.websvc.rest.wizard.Util;
0074: import org.openide.filesystems.FileObject;
0075: import org.openide.filesystems.FileUtil;
0076: import org.openide.util.NbBundle;
0077:
0078: /**
0079: *
0080: * @author PeterLiu
0081: */
0082: public class EntityResourcesGenerator extends AbstractGenerator {
0083:
0084: public static final String RESOURCE_FOLDER = "service"; //NOI18N
0085: public static final String CONVERTER_FOLDER = "converter"; //NOI18N
0086: public static final String RESOURCE_SUFFIX = GenericResourceBean.RESOURCE_SUFFIX;
0087: public static final String CONVERTER_SUFFIX = "Converter"; //NOI18N
0088: public static final String REF_CONVERTER_SUFFIX = "RefConverter"; //NOI18N
0089: public static final String REF_SUFFIX = "Ref"; //NOI18N
0090:
0091: private static final String DEFAULT_TEMPLATE = "Templates/WebServices/DefaultResource.java"; //NOI18N
0092: private static final String URI_RESOLVER_TEMPLATE = "Templates/WebServices/UriResolver.java"; //NOI18N
0093: private static final String URI_RESOLVER = "UriResolver";
0094: private static final String PERSISTENCE_SERVICE_TEMPLATE = "Templates/WebServices/PersistenceService.java"; //NOI18N
0095: private static final String PERSISTENCE_SERVICE = "PersistenceService"; //NOI18N
0096:
0097: private static final String DEFAULT_PU_FIELD = "DEFAULT_PU"; //NOI18N
0098:
0099: private static final String[] CONTAINER_IMPORTS = {
0100: RestConstants.PATH, RestConstants.GET, RestConstants.POST,
0101: RestConstants.PRODUCE_MIME, RestConstants.CONSUME_MIME,
0102: RestConstants.URI_PARAM, RestConstants.QUERY_PARAM,
0103: RestConstants.DEFAULT_VALUE, Constants.HTTP_RESPONSE,
0104: Constants.HTTP_CONTEXT, Constants.URI_INFO };
0105:
0106: private static final String[] ITEM_IMPORTS = { RestConstants.PATH,
0107: RestConstants.GET, RestConstants.PUT, RestConstants.DELETE,
0108: RestConstants.PRODUCE_MIME, RestConstants.CONSUME_MIME,
0109: Constants.WEB_APPLICATION_EXCEPTION,
0110: Constants.NO_RESULT_EXCEPTION };
0111:
0112: private static final String[] CONTAINER_CONVERTER_IMPORTS = {
0113: Constants.XML_ROOT_ELEMENT, Constants.XML_ELEMENT,
0114: Constants.XML_TRANSIENT, Constants.XML_ATTRIBUTE,
0115: Constants.ARRAY_LIST_TYPE };
0116:
0117: private static final String[] ITEM_CONVERTER_IMPORTS = {
0118: Constants.XML_ROOT_ELEMENT, Constants.XML_ELEMENT,
0119: Constants.XML_TRANSIENT, Constants.XML_ATTRIBUTE };
0120:
0121: private static final String[] REF_CONVERTER_IMPORTS = {
0122: Constants.XML_ROOT_ELEMENT, Constants.XML_ELEMENT,
0123: Constants.XML_TRANSIENT, Constants.XML_ATTRIBUTE };
0124:
0125: private static final String mimeTypes = "{\""
0126: + MimeType.XML.value() + "\", \"" + MimeType.JSON.value()
0127: + "\"}"; //NOI18N
0128:
0129: private String persistenceUnitName;
0130: private String targetPackageName;
0131: private FileObject targetFolder;
0132: private String packageName;
0133: private FileObject resourceFolder;
0134: private String resourcePackageName;
0135: private FileObject converterFolder;
0136: private String converterPackageName;
0137: private EntityResourceBeanModel model;
0138:
0139: /** Creates a new instance of EntityRESTServicesCodeGenerator */
0140: public EntityResourcesGenerator(EntityResourceBeanModel model,
0141: FileObject targetFolder, String targetPackageName,
0142: String persistenceUnitName) {
0143: this (model, targetFolder, targetPackageName, null, null,
0144: persistenceUnitName);
0145: }
0146:
0147: public EntityResourcesGenerator(EntityResourceBeanModel model,
0148: String resourcePackage, String converterPackage) {
0149: this (model, null, null, resourcePackage, converterPackage, null);
0150: }
0151:
0152: /** Creates a new instance of EntityRESTServicesCodeGenerator */
0153: public EntityResourcesGenerator(EntityResourceBeanModel model,
0154: FileObject targetFolder, String targetPackageName,
0155: String resourcePackage, String converterPackage,
0156: String persistenceUnitName) {
0157: this .model = model;
0158: this .persistenceUnitName = persistenceUnitName;
0159: this .targetFolder = targetFolder;
0160: this .targetPackageName = targetPackageName;
0161:
0162: if (resourcePackage == null) {
0163: this .resourcePackageName = targetPackageName + "."
0164: + this .RESOURCE_FOLDER;
0165: } else {
0166: this .resourcePackageName = resourcePackage;
0167: }
0168:
0169: if (converterPackage == null) {
0170: this .converterPackageName = targetPackageName + "."
0171: + this .CONVERTER_FOLDER;
0172: } else {
0173: this .converterPackageName = converterPackage;
0174: }
0175:
0176: this .packageName = packageName;
0177: }
0178:
0179: private String toFilePath(String packageName) {
0180: return packageName.replace(".", "/");
0181: }
0182:
0183: private FileObject getSourceRootFolder(FileObject packageFolder,
0184: String packageName) {
0185: String[] segments = packageName.split("\\.");
0186: FileObject ret = packageFolder;
0187: for (int i = segments.length - 1; i >= 0; i--) {
0188: String segment = segments[i];
0189:
0190: if (segment.length() == 0) {
0191: return ret;
0192: }
0193:
0194: if (ret == null || !segments[i].equals(ret.getNameExt())) {
0195: throw new IllegalArgumentException("Unmatched folder: "
0196: + packageFolder.getPath()
0197: + " and package name: " + packageName);
0198: }
0199: ret = ret.getParent();
0200: }
0201: return ret;
0202: }
0203:
0204: public Collection<String> previewClasses() {
0205: Collection<String> classes = new ArrayList<String>();
0206: Collection<EntityResourceBean> beans = model.getResourceBeans();
0207:
0208: for (EntityResourceBean bean : beans) {
0209: classes.add(getResourceType(bean));
0210: classes.add(getConverterType(bean));
0211: if (bean.isItem()) {
0212: classes.add(getRefConverterType(bean));
0213: }
0214: }
0215:
0216: classes.add(getPersistenceServiceClassType());
0217: classes.add(getUriResolverClassType());
0218:
0219: return Utils.sortKeys(classes);
0220: }
0221:
0222: public Set<FileObject> generate(ProgressHandle pHandle)
0223: throws IOException {
0224: initProgressReporting(pHandle);
0225:
0226: createFolders();
0227: generatePersistenceService();
0228: generateUriResolver();
0229:
0230: Map<EntityResourceBean, JavaSource> resourceMap = new HashMap<EntityResourceBean, JavaSource>();
0231: Map<EntityResourceBean, JavaSource> converterMap = new HashMap<EntityResourceBean, JavaSource>();
0232: Map<EntityResourceBean, JavaSource> refConverterMap = new HashMap<EntityResourceBean, JavaSource>();
0233:
0234: Collection<EntityResourceBean> resourceBeans = model
0235: .getResourceBeans();
0236:
0237: for (EntityResourceBean bean : resourceBeans) {
0238: resourceMap.put(bean, generateResourceBean(bean));
0239: converterMap.put(bean, generateConverter(bean));
0240:
0241: if (bean.isItem()) {
0242: refConverterMap.put(bean, generateRefConverter(bean));
0243: }
0244: }
0245:
0246: for (EntityResourceBean bean : resourceBeans) {
0247: modifyResourceBean(resourceMap.get(bean), bean);
0248: modifyConverter(converterMap.get(bean), bean);
0249:
0250: if (bean.isItem()) {
0251: modifyRefConverter(refConverterMap.get(bean), bean);
0252: }
0253: }
0254:
0255: finishProgressReporting();
0256:
0257: return new HashSet<FileObject>();
0258: }
0259:
0260: private void createFolders() {
0261: FileObject sourceRootFolder = getSourceRootFolder(targetFolder,
0262: targetPackageName);
0263: File sourceRootDir = FileUtil.toFile(sourceRootFolder);
0264: try {
0265: String resourceFolderPath = toFilePath(resourcePackageName);
0266: resourceFolder = sourceRootFolder
0267: .getFileObject(resourceFolderPath);
0268: if (resourceFolder == null) {
0269: resourceFolder = FileUtil.createFolder(new File(
0270: sourceRootDir, resourceFolderPath));
0271: }
0272:
0273: String converterFolderPath = toFilePath(converterPackageName);
0274: converterFolder = sourceRootFolder
0275: .getFileObject(converterFolderPath);
0276: if (converterFolder == null) {
0277: converterFolder = FileUtil.createFolder(new File(
0278: sourceRootDir, converterFolderPath));
0279: }
0280: } catch (IOException ex) {
0281: throw new IllegalArgumentException(ex);
0282: }
0283: }
0284:
0285: private void generatePersistenceService() {
0286: reportProgress(getPersistenceServiceClassType(), false);
0287:
0288: JavaSource source = JavaSourceHelper.createJavaSource(
0289: PERSISTENCE_SERVICE_TEMPLATE, resourceFolder,
0290: getResourcePackageName(), PERSISTENCE_SERVICE);
0291: if (source == null) {
0292: return;
0293: }
0294:
0295: reportProgress(getPersistenceServiceClassType(), true);
0296:
0297: // Modify the PU name
0298: try {
0299: ModificationResult result = source
0300: .runModificationTask(new AbstractTask<WorkingCopy>() {
0301: public void run(WorkingCopy copy)
0302: throws IOException {
0303: copy.toPhase(JavaSource.Phase.RESOLVED);
0304:
0305: JavaSourceHelper.replaceFieldValue(copy,
0306: JavaSourceHelper.getField(copy,
0307: DEFAULT_PU_FIELD),
0308: persistenceUnitName);
0309: }
0310: });
0311:
0312: result.commit();
0313: } catch (IOException ex) {
0314: ex.printStackTrace();
0315: }
0316: }
0317:
0318: private void generateUriResolver() {
0319: reportProgress(getUriResolverClassType(), false);
0320:
0321: JavaSource source = JavaSourceHelper.createJavaSource(
0322: URI_RESOLVER_TEMPLATE, converterFolder,
0323: getConverterPackageName(), URI_RESOLVER);
0324:
0325: reportProgress(getUriResolverClassType(), true);
0326:
0327: // Add PersistenceService import
0328: try {
0329: ModificationResult result = source
0330: .runModificationTask(new AbstractTask<WorkingCopy>() {
0331: public void run(WorkingCopy copy)
0332: throws IOException {
0333: copy.toPhase(JavaSource.Phase.RESOLVED);
0334:
0335: JavaSourceHelper
0336: .addImports(
0337: copy,
0338: new String[] { getPersistenceServiceClassType() });
0339: }
0340: });
0341:
0342: result.commit();
0343: } catch (IOException ex) {
0344: ex.printStackTrace();
0345: }
0346: }
0347:
0348: private JavaSource generateResourceBean(EntityResourceBean bean) {
0349: reportProgress(getResourceType(bean), false);
0350:
0351: return JavaSourceHelper.createJavaSource(DEFAULT_TEMPLATE,
0352: resourceFolder, getResourcePackageName(),
0353: getResourceName(bean));
0354: }
0355:
0356: private JavaSource generateConverter(EntityResourceBean bean) {
0357: reportProgress(getConverterType(bean), false);
0358:
0359: return JavaSourceHelper.createJavaSource(DEFAULT_TEMPLATE,
0360: converterFolder, getConverterPackageName(),
0361: getConverterName(bean));
0362: }
0363:
0364: private JavaSource generateRefConverter(EntityResourceBean bean) {
0365: reportProgress(getRefConverterType(bean), false);
0366:
0367: return JavaSourceHelper.createJavaSource(DEFAULT_TEMPLATE,
0368: converterFolder, getConverterPackageName(),
0369: getRefConverterName(bean));
0370: }
0371:
0372: private void modifyResourceBean(JavaSource source,
0373: EntityResourceBean bean) {
0374: reportProgress(getResourceType(bean), true);
0375:
0376: if (bean.isContainer()) {
0377: modifyContainerResourceBean(source, bean);
0378: } else {
0379: modifyItemResourceBean(source, bean);
0380: }
0381: }
0382:
0383: private void modifyContainerResourceBean(JavaSource source,
0384: final EntityResourceBean bean) {
0385: try {
0386: ModificationResult result = source
0387: .runModificationTask(new AbstractTask<WorkingCopy>() {
0388: public void run(WorkingCopy copy)
0389: throws IOException {
0390: copy.toPhase(JavaSource.Phase.RESOLVED);
0391:
0392: JavaSourceHelper.addImports(copy,
0393: getContainerResourceImports(bean));
0394:
0395: JavaSourceHelper
0396: .addClassAnnotation(
0397: copy,
0398: new String[] { RestConstants.PATH_ANNOTATION },
0399: new Object[] {
0400: bean
0401: .getUriTemplate(),
0402: JavaSourceHelper
0403: .createIdentifierTree(
0404: copy,
0405: "{"
0406: + getItemResourceName(bean)
0407: + ".class}") });
0408:
0409: ClassTree tree = JavaSourceHelper
0410: .getTopLevelClassTree(copy);
0411: ClassTree modifiedTree = tree;
0412:
0413: modifiedTree = addResourceBeanFields(copy,
0414: modifiedTree, bean);
0415: modifiedTree = addStatefulResourceBeanConstructor(
0416: copy, modifiedTree, bean);
0417: modifiedTree = addContainerGetMethod(copy,
0418: modifiedTree, bean, mimeTypes);
0419: modifiedTree = addContainerPostMethod(copy,
0420: modifiedTree, bean, mimeTypes);
0421:
0422: for (RelatedEntityResource relatedResource : bean
0423: .getSubResources()) {
0424: modifiedTree = addContainerGetResourceMethod(
0425: copy, modifiedTree, bean,
0426: relatedResource);
0427: }
0428:
0429: modifiedTree = addGetEntitiesMethod(copy,
0430: modifiedTree, bean);
0431: modifiedTree = addCreateEntityMethod(copy,
0432: modifiedTree, bean);
0433: //modifiedTree = addGetUriMethod(copy, modifiedTree, bean);
0434:
0435: copy.rewrite(tree, modifiedTree);
0436: }
0437: });
0438:
0439: result.commit();
0440: } catch (IOException ex) {
0441: ex.printStackTrace();
0442: }
0443: }
0444:
0445: private void modifyItemResourceBean(JavaSource source,
0446: final EntityResourceBean bean) {
0447: try {
0448: ModificationResult result = source
0449: .runModificationTask(new AbstractTask<WorkingCopy>() {
0450: public void run(WorkingCopy copy)
0451: throws IOException {
0452: copy.toPhase(JavaSource.Phase.RESOLVED);
0453:
0454: JavaSourceHelper.addImports(copy,
0455: getItemResourceImports(bean));
0456:
0457: /*
0458: JavaSourceHelper.addClassAnnotation(copy,
0459: new String[] {Constants.URI_TEMPLATE_ANNOTATION},
0460: new Object[] {bean.getUriTemplate()});
0461: */
0462:
0463: ClassTree tree = JavaSourceHelper
0464: .getTopLevelClassTree(copy);
0465: ClassTree modifiedTree = tree;
0466:
0467: modifiedTree = addResourceBeanFields(copy,
0468: modifiedTree, bean);
0469: modifiedTree = addStatefulResourceBeanConstructor(
0470: copy, modifiedTree, bean);
0471: modifiedTree = addItemGetMethod(copy,
0472: modifiedTree, bean, mimeTypes);
0473: modifiedTree = addItemPutMethod(copy,
0474: modifiedTree, bean, mimeTypes);
0475:
0476: modifiedTree = addItemDeleteMethod(copy,
0477: modifiedTree, bean);
0478:
0479: for (RelatedEntityResource relatedResource : bean
0480: .getSubResources()) {
0481: modifiedTree = addItemGetResourceMethod(
0482: copy, modifiedTree, bean,
0483: relatedResource);
0484: }
0485:
0486: modifiedTree = addGetEntityMethod(copy,
0487: modifiedTree, bean);
0488: modifiedTree = addUpdateEntityMethod(copy,
0489: modifiedTree, bean);
0490: //modifiedTree = addGetUriMethod(copy, modifiedTree, bean);
0491:
0492: copy.rewrite(tree, modifiedTree);
0493: }
0494: });
0495:
0496: result.commit();
0497: } catch (IOException ex) {
0498: ex.printStackTrace();
0499: }
0500: }
0501:
0502: private void modifyConverter(JavaSource source,
0503: EntityResourceBean bean) {
0504: reportProgress(getConverterType(bean), true);
0505:
0506: if (bean.isContainer()) {
0507: modifyContainerConverter(source, bean);
0508: } else {
0509: modifyItemConverter(source, bean);
0510: }
0511: }
0512:
0513: private void modifyContainerConverter(JavaSource source,
0514: final EntityResourceBean bean) {
0515: try {
0516: ModificationResult result = source
0517: .runModificationTask(new AbstractTask<WorkingCopy>() {
0518: public void run(WorkingCopy copy)
0519: throws IOException {
0520: copy.toPhase(JavaSource.Phase.RESOLVED);
0521:
0522: JavaSourceHelper.addImports(copy,
0523: CONTAINER_CONVERTER_IMPORTS);
0524:
0525: ClassTree tree = JavaSourceHelper
0526: .getTopLevelClassTree(copy);
0527: ClassTree modifiedTree = tree;
0528:
0529: JavaSourceHelper
0530: .addClassAnnotation(
0531: copy,
0532: new String[] { Constants.XML_ROOT_ELEMENT_ANNOTATION },
0533: new Object[] { JavaSourceHelper
0534: .createAssignmentTree(
0535: copy,
0536: "name",
0537: getConverterXMLName(bean)) });
0538:
0539: modifiedTree = addConverterFields(copy,
0540: modifiedTree, bean, false);
0541: modifiedTree = addConverterConstructor(
0542: copy, modifiedTree, bean, false);
0543: modifiedTree = addGetReferencesMethod(copy,
0544: modifiedTree, bean);
0545: modifiedTree = addSetReferencesMethod(copy,
0546: modifiedTree, bean);
0547: modifiedTree = addGetUriMethod(copy,
0548: modifiedTree);
0549: modifiedTree = addContainerConverterGetEntitiesMethod(
0550: copy, modifiedTree, bean);
0551:
0552: copy.rewrite(tree, modifiedTree);
0553: }
0554: });
0555:
0556: result.commit();
0557: } catch (IOException ex) {
0558: ex.printStackTrace();
0559: }
0560: }
0561:
0562: private void modifyItemConverterDefaultConstructor(
0563: JavaSource source, final EntityResourceBean bean) {
0564: try {
0565: ModificationResult result = source
0566: .runModificationTask(new AbstractTask<WorkingCopy>() {
0567: public void run(WorkingCopy copy)
0568: throws IOException {
0569: copy.toPhase(JavaSource.Phase.RESOLVED);
0570:
0571: JavaSourceHelper
0572: .addImports(
0573: copy,
0574: new String[] { getEntityClassType(bean) });
0575:
0576: String bodyText = "{ entity = new $CLASS$(); }";
0577: bodyText = bodyText.replace("$CLASS$",
0578: getEntityClassName(bean));
0579:
0580: JavaSourceHelper
0581: .replaceMethodBody(
0582: copy,
0583: JavaSourceHelper
0584: .getDefaultConstructor(copy),
0585: bodyText);
0586: }
0587: });
0588: result.commit();
0589:
0590: } catch (IOException ex) {
0591: ex.printStackTrace();
0592: }
0593: }
0594:
0595: private void modifyItemConverter(JavaSource source,
0596: final EntityResourceBean bean) {
0597: modifyItemConverterDefaultConstructor(source, bean);
0598:
0599: try {
0600: ModificationResult result = source
0601: .runModificationTask(new AbstractTask<WorkingCopy>() {
0602: public void run(WorkingCopy copy)
0603: throws IOException {
0604: copy.toPhase(JavaSource.Phase.RESOLVED);
0605:
0606: JavaSourceHelper.addImports(copy,
0607: ITEM_CONVERTER_IMPORTS);
0608:
0609: ClassTree tree = JavaSourceHelper
0610: .getTopLevelClassTree(copy);
0611: ClassTree modifiedTree = tree;
0612:
0613: JavaSourceHelper
0614: .addClassAnnotation(
0615: copy,
0616: new String[] { Constants.XML_ROOT_ELEMENT_ANNOTATION },
0617: new Object[] { JavaSourceHelper
0618: .createAssignmentTree(
0619: copy,
0620: "name",
0621: getConverterXMLName(bean)) });
0622:
0623: modifiedTree = addConverterFields(copy,
0624: modifiedTree, bean, false);
0625: modifiedTree = addConverterConstructor(
0626: copy, modifiedTree, bean, false);
0627:
0628: for (FieldInfo fieldInfo : bean
0629: .getEntityClassInfo()
0630: .getFieldInfos()) {
0631: modifiedTree = addGetterMethod(copy,
0632: modifiedTree, fieldInfo);
0633: modifiedTree = addSetterMethod(copy,
0634: modifiedTree, fieldInfo, bean);
0635: }
0636:
0637: modifiedTree = addGetUriMethod(copy,
0638: modifiedTree);
0639: modifiedTree = addItemConverterGetEntityMethod(
0640: copy, modifiedTree, bean);
0641: modifiedTree = addItemConverterSetEntityMethod(
0642: copy, modifiedTree, bean);
0643:
0644: copy.rewrite(tree, modifiedTree);
0645: }
0646: });
0647:
0648: result.commit();
0649: } catch (IOException ex) {
0650: ex.printStackTrace();
0651: }
0652: }
0653:
0654: private void modifyRefConverter(JavaSource source,
0655: final EntityResourceBean bean) {
0656: reportProgress(getRefConverterType(bean), true);
0657:
0658: try {
0659: ModificationResult result = source
0660: .runModificationTask(new AbstractTask<WorkingCopy>() {
0661: public void run(WorkingCopy copy)
0662: throws IOException {
0663: copy.toPhase(JavaSource.Phase.RESOLVED);
0664:
0665: JavaSourceHelper.addImports(copy,
0666: REF_CONVERTER_IMPORTS);
0667:
0668: ClassTree tree = JavaSourceHelper
0669: .getTopLevelClassTree(copy);
0670: ClassTree modifiedTree = tree;
0671:
0672: JavaSourceHelper
0673: .addClassAnnotation(
0674: copy,
0675: new String[] { Constants.XML_ROOT_ELEMENT_ANNOTATION },
0676: new Object[] { JavaSourceHelper
0677: .createAssignmentTree(
0678: copy,
0679: "name",
0680: getRefConverterXMLName(bean)) }); //NOI18N
0681:
0682: modifiedTree = addConverterFields(copy,
0683: modifiedTree, bean, true);
0684: modifiedTree = addConverterConstructor(
0685: copy, modifiedTree, bean, true);
0686:
0687: FieldInfo fieldInfo = bean
0688: .getEntityClassInfo()
0689: .getIdFieldInfo();
0690: modifiedTree = addGetterMethod(copy,
0691: modifiedTree, fieldInfo);
0692: modifiedTree = addGetUriMethod(copy,
0693: modifiedTree, fieldInfo);
0694: modifiedTree = addSetUriMethod(copy,
0695: modifiedTree, fieldInfo);
0696: modifiedTree = addRefConverterGetEntityMethod(
0697: copy, modifiedTree, bean);
0698:
0699: copy.rewrite(tree, modifiedTree);
0700: }
0701: });
0702:
0703: result.commit();
0704: } catch (IOException ex) {
0705: ex.printStackTrace();
0706: }
0707: }
0708:
0709: private String[] getContainerResourceImports(EntityResourceBean bean) {
0710: List<String> imports = new ArrayList<String>(Arrays
0711: .asList(CONTAINER_IMPORTS));
0712:
0713: Set<String> entityClasses = new HashSet<String>();
0714: EntityResourceBean itemBean = getItemSubResource(bean);
0715:
0716: for (RelatedEntityResource resource : itemBean
0717: .getSubResources()) {
0718: if (resource.getFieldInfo().isOneToMany()) {
0719: entityClasses.add(getEntityClassType(resource
0720: .getResourceBean()));
0721: }
0722: }
0723:
0724: imports.addAll(entityClasses);
0725: imports.add(getConverterType(bean));
0726: imports.add(getConverterType(getItemConverterBean(bean)));
0727:
0728: return imports.toArray(new String[imports.size()]);
0729: }
0730:
0731: private String[] getItemResourceImports(EntityResourceBean bean) {
0732: List<String> imports = new ArrayList<String>(Arrays
0733: .asList(ITEM_IMPORTS));
0734:
0735: Set<String> classes = new HashSet<String>();
0736: for (RelatedEntityResource resource : bean.getSuperResources()) {
0737: classes.add(getEntityClassType(resource.getResourceBean()));
0738: }
0739:
0740: for (RelatedEntityResource resource : bean.getSubResources()) {
0741: EntityResourceBean subBean = resource.getResourceBean();
0742:
0743: if (subBean.isContainer()) {
0744: classes.add(Constants.COLLECTION_TYPE);
0745: } else {
0746: //Only add non java.lang types.
0747: String type = getIdFieldType(subBean);
0748: if (!type.startsWith("java.lang.")) {
0749: classes.add(type);
0750: }
0751: }
0752: }
0753: imports.addAll(classes);
0754: imports.add(getConverterType(bean));
0755:
0756: return imports.toArray(new String[imports.size()]);
0757: }
0758:
0759: private EntityResourceBean getItemConverterBean(
0760: EntityResourceBean containerBean) {
0761: return model.getItemResourceBean(containerBean
0762: .getEntityClassInfo());
0763: }
0764:
0765: private ClassTree addResourceBeanFields(WorkingCopy copy,
0766: ClassTree tree, EntityResourceBean bean) {
0767: Modifier[] modifiers = new Modifier[] { Modifier.PRIVATE };
0768: ClassTree modifiedTree = tree;
0769:
0770: String[] annotations = null;
0771:
0772: if (bean.isContainer()) {
0773: annotations = new String[] { RestConstants.HTTP_CONTEXT_ANNOTATION };
0774: }
0775:
0776: modifiedTree = JavaSourceHelper.addField(copy, modifiedTree,
0777: modifiers, annotations, null, "context",
0778: Constants.URI_INFO); //NOI18
0779:
0780: if (!bean.isContainer()) {
0781: String ids[] = getIdFieldIdArray(bean, false, null);
0782: Object types[] = getIdFieldTypeArray(bean, false, null);
0783:
0784: for (int i = 0; i < ids.length; i++) {
0785: modifiedTree = JavaSourceHelper.addField(copy,
0786: modifiedTree, modifiers, annotations, null,
0787: ids[i], (String) types[i]); //NOI18
0788: }
0789: }
0790:
0791: return modifiedTree;
0792: }
0793:
0794: private ClassTree addStatefulResourceBeanConstructor(
0795: WorkingCopy copy, ClassTree tree, EntityResourceBean bean) {
0796: String[] parameters = null;
0797: Object[] types = null;
0798:
0799: if (bean.isContainer()) {
0800: parameters = new String[] { "context" };
0801: types = new String[] { Constants.URI_INFO };
0802: } else {
0803: parameters = getIdFieldIdArray(bean, true, "context");
0804: types = getIdFieldTypeArray(bean, true, Constants.URI_INFO);
0805: }
0806:
0807: String bodyText = "{";
0808: for (int i = 0; i < parameters.length; i++) {
0809: bodyText += "this." + parameters[i] + " = " + parameters[i]
0810: + ";";
0811: }
0812: bodyText += "}";
0813:
0814: String comment = "Constructor used for instantiating an instance of dynamic resource.\n\n"
0815: + "@param context HttpContext inherited from the parent resource";
0816:
0817: return JavaSourceHelper.addConstructor(copy, tree,
0818: new Modifier[] { Modifier.PUBLIC }, parameters, types,
0819: bodyText, comment);
0820: }
0821:
0822: private ClassTree addContainerGetMethod(WorkingCopy copy,
0823: ClassTree tree, EntityResourceBean bean, String mimeTypes) {
0824: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
0825: String methodName = HttpMethodType.GET.prefix();
0826: String[] annotations = new String[] {
0827: RestConstants.GET_ANNOTATION,
0828: RestConstants.PRODUCE_MIME_ANNOTATION };
0829:
0830: Object[] annotationAttrs = new Object[] { null,
0831: JavaSourceHelper.createIdentifierTree(copy, mimeTypes) };
0832:
0833: Object returnType = getConverterType(bean);
0834:
0835: String[] parameters = new String[] { "start", "max" }; //NOI18N
0836: Object[] paramTypes = new String[] { "int", "int" }; //NOI18N
0837: String[][] paramAnnotations = new String[][] {
0838: { RestConstants.QUERY_PARAM_ANNOTATION,
0839: RestConstants.DEFAULT_VALUE_ANNOTATION },
0840: { RestConstants.QUERY_PARAM_ANNOTATION,
0841: RestConstants.DEFAULT_VALUE_ANNOTATION } };
0842:
0843: Object[][] paramAnnotationAttrs = new Object[][] {
0844: { "start", "0" }, { "max", "10" } };
0845:
0846: String bodyText = "{ try {"
0847: + "return new $CONVERTER$(getEntities(start, max), context.getAbsolutePath());"
0848: + "} finally {"
0849: + "PersistenceService.getInstance().close();" + "}"
0850: + "}";
0851: bodyText = bodyText.replace("$CONVERTER$",
0852: getConverterName(bean));
0853:
0854: String comment = "Get method for retrieving a collection of $CLASS$ instance in XML format.\n\n"
0855: + "@return an instance of $CONVERTER$";
0856: comment = comment.replace("$CLASS$", getEntityClassName(bean))
0857: .replace("$CONVERTER$", getConverterName(bean));
0858:
0859: return JavaSourceHelper.addMethod(copy, tree, modifiers,
0860: annotations, annotationAttrs, methodName, returnType,
0861: parameters, paramTypes, paramAnnotations,
0862: paramAnnotationAttrs, bodyText, comment); //NOI18N
0863: }
0864:
0865: private ClassTree addContainerPostMethod(WorkingCopy copy,
0866: ClassTree tree, EntityResourceBean bean, String mimeTypes) {
0867: String methodName = HttpMethodType.POST.prefix();
0868: String[] annotations = new String[] {
0869: RestConstants.POST_ANNOTATION,
0870: RestConstants.CONSUME_MIME_ANNOTATION };
0871: Object[] annotationAttrs = new Object[] { null,
0872: JavaSourceHelper.createIdentifierTree(copy, mimeTypes) };
0873: //Object returnType = getConverterType(model.getItemResourceBean(bean.getEntityClassInfo()));
0874: Object returnType = Constants.HTTP_RESPONSE;
0875:
0876: String[] params = new String[] { "data" };
0877: Object[] paramTypes = new Object[] { getItemConverterName(bean) };
0878:
0879: String bodyText = "{"
0880: + "PersistenceService service = PersistenceService.getInstance();"
0881: + "try {"
0882: + "service.beginTx();"
0883: + "$CLASS$ entity = data.getEntity();"
0884: + "createEntity(entity);"
0885: + "service.commitTx();"
0886: + "return Response.created(context.getAbsolutePath().resolve($ID_TO_URI$ + \"/\")).build();"
0887: + "} finally {" + "service.close();" + "}" + "}";
0888:
0889: bodyText = bodyText
0890: .replace("$CLASS$", getEntityClassName(bean)).replace(
0891: "$ID_TO_URI$", getIdFieldToUriStmt(bean));
0892:
0893: String comment = "Post method for creating an instance of $CLASS$ using XML as the input format.\n\n"
0894: + "@param data an $CONVERTER$ entity that is deserialized from an XML stream\n"
0895: + "@return an instance of $CONVERTER$";
0896:
0897: comment = comment.replace("$CLASS$", getEntityClassName(bean))
0898: .replace("$CONVERTER$", getItemConverterName(bean));
0899:
0900: return JavaSourceHelper.addMethod(copy, tree, Constants.PUBLIC,
0901: annotations, annotationAttrs, methodName, returnType,
0902: params, paramTypes, null, null, bodyText, comment);
0903: }
0904:
0905: private ClassTree addContainerGetResourceMethod(WorkingCopy copy,
0906: ClassTree tree, EntityResourceBean bean,
0907: RelatedEntityResource relatedResource) {
0908: EntityResourceBean subBean = relatedResource.getResourceBean();
0909: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
0910: String[] annotations = new String[] { RestConstants.PATH_ANNOTATION };
0911: String[] annotationAttrs = new String[] { subBean
0912: .getUriTemplate() };
0913: Object returnType = getResourceType(subBean);
0914: String resourceName = getResourceName(subBean);
0915: String methodName = "get" + resourceName;
0916:
0917: String[] parameters = getIdFieldIdArray(subBean, false, null);
0918: Object[] paramTypes = getIdFieldTypeArray(subBean, false, null);
0919: String[] paramAnnotations = getIdFieldUriParamArray(subBean,
0920: false, null);
0921: Object[] paramAnnotationAttrs = getIdFieldNameArray(subBean,
0922: false, null);
0923: String argList = getIdFieldIdList(subBean) + ", context";
0924:
0925: String bodyText = "{ return new $RESOURCE$(" + argList + "); }";
0926: bodyText = bodyText.replace("$RESOURCE$", resourceName);
0927:
0928: String comment = "Returns a dynamic instance of $RESOURCE$ used for entity navigation.\n\n"
0929: + "@return an instance of $RESOURCE$";
0930:
0931: comment = comment.replace("$RESOURCE$",
0932: getResourceName(subBean));
0933:
0934: return JavaSourceHelper.addMethod(copy, tree, modifiers,
0935: annotations, annotationAttrs, methodName, returnType,
0936: parameters, paramTypes, paramAnnotations,
0937: paramAnnotationAttrs, bodyText, comment);
0938: }
0939:
0940: private ClassTree addGetEntitiesMethod(WorkingCopy copy,
0941: ClassTree tree, EntityResourceBean bean) {
0942: Modifier[] modifiers = new Modifier[] { Modifier.PROTECTED };
0943: Tree returnType = JavaSourceHelper.createParameterizedTypeTree(
0944: copy, Constants.COLLECTION_TYPE,
0945: new String[] { getEntityClassType(bean) });
0946:
0947: String bodyText = "{"
0948: + "return PersistenceService.getInstance().createQuery(\"SELECT e FROM $CLASS$ e\")."
0949: + "setFirstResult(start).setMaxResults(max).getResultList();"
0950: + "}";
0951:
0952: String[] parameters = new String[] { "start", "max" };
0953: Object[] paramTypes = new Object[] { "int", "int" };
0954:
0955: bodyText = bodyText
0956: .replace("$CLASS$", getEntityClassName(bean));
0957:
0958: String comment = "Returns all the entities associated with this resource.\n\n"
0959: + "@return a collection of $CLASS$ instances";
0960: comment = comment.replace("$CLASS$", getEntityClassName(bean));
0961:
0962: return JavaSourceHelper.addMethod(copy, tree, modifiers, null,
0963: null, "getEntities", returnType, parameters,
0964: paramTypes, null, null, bodyText, comment);
0965: }
0966:
0967: private String getGetEntitiesSubText(EntityResourceBean bean) {
0968: String template = "if (parent instanceof $CLASS$) {"
0969: + "return (($CLASS$) parent).$GETTER$();}";
0970:
0971: String bodyText = "";
0972:
0973: for (RelatedEntityResource relatedResource : bean
0974: .getSuperResources()) {
0975: EntityResourceBean super Bean = relatedResource
0976: .getResourceBean();
0977: FieldInfo fieldInfo = relatedResource.getFieldInfo();
0978:
0979: bodyText = bodyText
0980: + template.replace("$CLASS$",
0981: getEntityClassName(super Bean)).replace(
0982: "$GETTER$", getGetterName(fieldInfo));
0983: }
0984:
0985: return bodyText;
0986: }
0987:
0988: private ClassTree addCreateEntityMethod(WorkingCopy copy,
0989: ClassTree tree, EntityResourceBean bean) {
0990: Modifier[] modifiers = new Modifier[] { Modifier.PROTECTED };
0991: Object returnType = Constants.VOID; //getEntityClassType(bean);
0992: String[] params = new String[] { "entity" };
0993: Object[] paramTypes = new Object[] { getEntityClassType(bean) };
0994:
0995: String bodyText = "{"
0996: + "PersistenceService.getInstance().persistEntity(entity);";
0997:
0998: bodyText = bodyText
0999: + getUpdateOneToManyRelSubText(getItemSubResource(bean))
1000: + "}";
1001:
1002: String comment = "Persist the given entity.\n\n"
1003: + "@param entity the entity to persist";
1004:
1005: return JavaSourceHelper.addMethod(copy, tree, modifiers, null,
1006: null, "createEntity", returnType, params, paramTypes,
1007: null, null, bodyText, comment);
1008: }
1009:
1010: private ClassTree addGetUriMethod(WorkingCopy copy, ClassTree tree,
1011: EntityResourceBean bean) {
1012: String bodyText = "{return context.getAbsolutePath();}";
1013:
1014: String comment = "Returns the URI associated with this resource.\n\n"
1015: + "@return URI associated with this resource";
1016:
1017: return JavaSourceHelper.addMethod(copy, tree,
1018: new Modifier[] { Modifier.PRIVATE }, null, null,
1019: "getUri", Constants.URI_TYPE, null, null, null, null,
1020: bodyText, comment);
1021: }
1022:
1023: private ClassTree addItemGetMethod(WorkingCopy copy,
1024: ClassTree tree, EntityResourceBean bean, String mimeTypes) {
1025: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1026: String methodName = HttpMethodType.GET.prefix();
1027: String[] annotations = new String[] {
1028: RestConstants.GET_ANNOTATION,
1029: RestConstants.PRODUCE_MIME_ANNOTATION };
1030:
1031: Object[] annotationAttrs = new Object[] { null,
1032: JavaSourceHelper.createIdentifierTree(copy, mimeTypes) };
1033:
1034: Object returnType = getConverterType(bean);
1035:
1036: String bodyText = "{ try {"
1037: + "return new $CONVERTER$(getEntity(), context.getAbsolutePath()); "
1038: + "} finally {"
1039: + "PersistenceService.getInstance().close();" + "}"
1040: + "}";
1041:
1042: bodyText = bodyText.replace("$CONVERTER$",
1043: getConverterName(bean));
1044:
1045: String comment = "Get method for retrieving an instance of $CLASS identified by id in XML format.\n\n"
1046: + "@param id identifier for the entity\n"
1047: + "@return an instance of $CONVERTER$";
1048: comment = comment.replace("$CLASS", getEntityClassName(bean))
1049: .replace("$CONVERTER$", getConverterName(bean));
1050:
1051: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1052: annotations, annotationAttrs, methodName, returnType,
1053: null, null, null, null, bodyText, comment); //NOI18N
1054: }
1055:
1056: private ClassTree addItemPutMethod(WorkingCopy copy,
1057: ClassTree tree, EntityResourceBean bean, String mimeTypes) {
1058: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1059: String methodName = HttpMethodType.PUT.prefix();
1060: String[] annotations = new String[] {
1061: RestConstants.PUT_ANNOTATION,
1062: RestConstants.CONSUME_MIME_ANNOTATION };
1063:
1064: Object[] annotationAttrs = new Object[] { null,
1065: JavaSourceHelper.createIdentifierTree(copy, mimeTypes) };
1066:
1067: String[] params = new String[] { "data" };
1068: Object[] paramTypes = new String[] { getConverterType(bean) };
1069:
1070: String bodyText = "{ "
1071: + "PersistenceService service = PersistenceService.getInstance();"
1072: + "try {" + "service.beginTx();"
1073: + "updateEntity(getEntity(), data.getEntity());"
1074: + "service.commitTx();" + "} finally {"
1075: + "service.close();" + "}" + "}";
1076:
1077: String comment = "Put method for updating an instance of $CLASS identified by id using XML as the input format.\n\n"
1078: + "@param id identifier for the entity\n"
1079: + "@param data an $CONVERTER$ entity that is deserialized from a XML stream\n";
1080:
1081: comment = comment.replace("$CLASS", getEntityClassName(bean))
1082: .replace("$CONVERTER$", getConverterName(bean));
1083:
1084: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1085: annotations, annotationAttrs, methodName,
1086: Constants.VOID, params, paramTypes, null, null,
1087: bodyText, comment);
1088: }
1089:
1090: private ClassTree addItemDeleteMethod(WorkingCopy copy,
1091: ClassTree tree, EntityResourceBean bean) {
1092: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1093: Object returnType = Constants.VOID;
1094:
1095: String[] annotations = new String[] { RestConstants.DELETE_ANNOTATION };
1096: Object[] annotationAttrs = new Object[] { null };
1097:
1098: String bodyText = "{"
1099: + "PersistenceService service = PersistenceService.getInstance();"
1100: + "try {" + "service.beginTx();"
1101: + "$CLASS$ entity = getEntity();"
1102: + "service.removeEntity(entity);"
1103: + "service.commitTx();" + "} finally {"
1104: + "service.close();" + "}" + "}";
1105: bodyText = bodyText
1106: .replace("$CLASS$", getEntityClassName(bean));
1107:
1108: String comment = "Delete method for deleting an instance of $CLASS identified by id.\n\n"
1109: + "@param id identifier for the entity\n";
1110: comment = comment.replace("$CLASS", getEntityClassName(bean));
1111:
1112: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1113: annotations, annotationAttrs, HttpMethodType.DELETE
1114: .prefix(), returnType, null, null, null, null,
1115: bodyText, comment);
1116: }
1117:
1118: private ClassTree addItemGetResourceMethod(WorkingCopy copy,
1119: ClassTree tree, EntityResourceBean bean,
1120: RelatedEntityResource relatedResource) {
1121: EntityResourceBean subBean = relatedResource.getResourceBean();
1122: FieldInfo fieldInfo = relatedResource.getFieldInfo();
1123: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1124: String[] annotations = new String[] { RestConstants.PATH_ANNOTATION };
1125:
1126: String uriTemplate = lowerCaseFirstLetter(subBean.getName())
1127: + "/";
1128: String[] annotationAttrs = new String[] { uriTemplate };
1129: Object returnType = getResourceType(subBean);
1130: String resourceName = getResourceName(subBean);
1131:
1132: // Check to see if there is any conflict.
1133: boolean hasConflict = false;
1134: for (RelatedEntityResource resource : bean.getSubResources()) {
1135: if (resource != relatedResource) {
1136: if (resourceName.equals(getResourceName(resource
1137: .getResourceBean()))) {
1138: hasConflict = true;
1139: break;
1140: }
1141: }
1142: }
1143:
1144: String methodName = "get" + resourceName; //NOI18N
1145:
1146: if (hasConflict) {
1147: methodName += "For"
1148: + capitalizeFirstLetter(fieldInfo.getName()); //NOI18N
1149: }
1150:
1151: String bodyText = null;
1152:
1153: if (subBean.isItem()) {
1154: bodyText = "{"
1155: + "final $CLASS$ parent = getEntity();"
1156: + "return new $RESOURCE$(null, context) {"
1157: + "@Override protected $SUBCLASS$ getEntity() {"
1158: + "$SUBCLASS$ entity = parent.$GETTER$();"
1159: + "if (entity == null) {"
1160: + "throw new WebApplicationException(new Throwable(\"Resource for \" + context.getAbsolutePath() + \" does not exist.\"), 404);"
1161: + "}" + "return entity;" + "}" + "};" + "}";
1162: bodyText = bodyText.replace("$CLASS$",
1163: getEntityClassName(bean)).replace("$RESOURCE$",
1164: resourceName).replace("$SUBCLASS$",
1165: getEntityClassName(subBean)).replace("$ID_PARAMS$",
1166: getIdFieldParamList(subBean)).replace("$GETTER$",
1167: getGetterName(fieldInfo));
1168: } else {
1169: bodyText = "{"
1170: + "final $CLASS$ parent = getEntity();"
1171: + "return new $RESOURCE$(context) {"
1172: + "@Override protected Collection<$SUBCLASS$> getEntities(int start, int max) {"
1173: + "Collection<$SUBCLASS$> result = new java.util.ArrayList<$SUBCLASS$>();"
1174: + "int index = 0;"
1175: + "for ($SUBCLASS$ e : parent.$GETTER$()) {"
1176: + "if (index >= start && (index - start) < max) {"
1177: + "result.add(e);"
1178: + "}"
1179: + "index++;"
1180: + "}"
1181: + "return result;"
1182: + "}"
1183: + "@Override protected void createEntity($SUBCLASS$ entity) {"
1184: + "super.createEntity(entity);";
1185:
1186: if (fieldInfo.isOneToMany()) {
1187: bodyText += "entity.$SETTER$(parent);";
1188:
1189: for (RelatedEntityResource subResource : getItemSubResource(
1190: subBean).getSubResources()) {
1191: if (bean == subResource.getResourceBean()) {
1192: bodyText = bodyText.replace("$SETTER$",
1193: getSetterName(subResource
1194: .getFieldInfo()));
1195:
1196: break;
1197: }
1198: }
1199: } else if (fieldInfo.isManyToMany()) {
1200: bodyText += "if (!entity.$GETTER2$().contains(parent)) {"
1201: + "entity.$GETTER2$().add(parent);" + "}";
1202:
1203: for (RelatedEntityResource subResource : getItemSubResource(
1204: subBean).getSubResources()) {
1205: EntityResourceBean subSubBean = subResource
1206: .getResourceBean();
1207: if (subSubBean.isContainer()) {
1208: if (bean == getItemSubResource(subSubBean)) {
1209: bodyText = bodyText.replace("$GETTER2$",
1210: getGetterName(subResource
1211: .getFieldInfo()));
1212:
1213: break;
1214: }
1215: }
1216: }
1217: }
1218:
1219: bodyText += "}};}";
1220:
1221: bodyText = bodyText.replace("$CLASS$",
1222: getEntityClassName(bean)).replace("$RESOURCE$",
1223: resourceName).replace("$SUBCLASS$",
1224: getEntityClassName(subBean)).replace("$GETTER$",
1225: getGetterName(fieldInfo));
1226: }
1227:
1228: String comment = "Returns a dynamic instance of $RESOURCE$ used for entity navigation.\n\n"
1229: + "@param id identifier for the parent entity\n"
1230: + "@return an instance of $RESOURCE$";
1231:
1232: comment = comment.replace("$RESOURCE$",
1233: getResourceName(subBean));
1234:
1235: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1236: annotations, annotationAttrs, methodName, returnType,
1237: null, null, null, null, bodyText, comment);
1238: }
1239:
1240: private ClassTree addGetEntityMethod(WorkingCopy copy,
1241: ClassTree tree, EntityResourceBean bean) {
1242: Modifier[] modifiers = new Modifier[] { Modifier.PROTECTED };
1243: FieldInfo idField = bean.getEntityClassInfo().getIdFieldInfo();
1244:
1245: String idString = "id";
1246: String newIdStatement = "";
1247: String idType = idField.getType();
1248:
1249: if (idField.isEmbeddedId()) {
1250: newIdStatement = idType + " id = new " + idType + "("
1251: + getIdFieldIdList(bean) + ");";
1252: } else {
1253: // Temporary workaround because Jersey does not support Character type
1254: // in UriParam.
1255: if (idType.equals("java.lang.Character")) { //NOI18N
1256: idString = "id.charAt(0)";
1257: }
1258: }
1259:
1260: String bodyText = "{"
1261: + "try {"
1262: + "$NEW_ID_STMT$"
1263: + "return ($CLASS$) PersistenceService.getInstance()."
1264: + "createQuery(\"SELECT e FROM $CLASS$ e where e.$ID$ = :$ID$\")."
1265: + "setParameter(\"$ID$\", $ID_STRING$).getSingleResult();"
1266: + "} catch (NoResultException ex) {"
1267: + "throw new WebApplicationException(new Throwable(\"Resource for \" + context.getAbsolutePath() + \" does not exist.\"), 404);"
1268: + "}" + "}";
1269:
1270: String id = bean.getEntityClassInfo().getIdFieldInfo()
1271: .getName();
1272: bodyText = bodyText.replace("$NEW_ID_STMT$", newIdStatement)
1273: .replace("$CLASS$", getEntityClassName(bean)).replace(
1274: "$ID$", id).replace("$ID_STRING$", idString);
1275:
1276: String comment = "Returns an instance of $CLASS$ identified by id.\n\n"
1277: + "@param id identifier for the entity\n"
1278: + "@return an instance of $CLASS$";
1279: comment = comment.replace("$CLASS$", getEntityClassName(bean));
1280:
1281: return JavaSourceHelper.addMethod(copy, tree, modifiers, null,
1282: null, "getEntity", getEntityClassType(bean), null,
1283: null, null, null, bodyText, comment);
1284: }
1285:
1286: private String getGetEntitySubText(EntityResourceBean bean) {
1287: String template1 = "if (parent instanceof $SUPERCLASS$) {"
1288: + "for ($CLASS$ e : (($SUPERCLASS$) parent).$SUPERGETTER$()) {"
1289: + "if (e.$GETTER$().equals(id)) {" + "return e;"
1290: + "}}}";
1291:
1292: String template2 = "if (parent instanceof $SUPERCLASS$) {"
1293: + "return (($SUPERCLASS$) parent).$SUPERGETTER$();"
1294: + "}";
1295:
1296: String bodyText = "";
1297:
1298: for (RelatedEntityResource resource : bean.getSuperResources()) {
1299: EntityResourceBean super Bean = resource.getResourceBean();
1300: FieldInfo fieldInfo = resource.getFieldInfo();
1301: String template = null;
1302:
1303: // Skip 1-to-M relationships.
1304: if (fieldInfo.isOneToMany()) {
1305: //template = template1;
1306: continue;
1307: } else {
1308: template = template2;
1309: }
1310:
1311: bodyText = bodyText
1312: + template.replace("$SUPERCLASS$",
1313: getEntityClassName(super Bean)).replace(
1314: "$SUPERGETTER$", getGetterName(fieldInfo))
1315: .replace("$CLASS$",
1316: getEntityClassName(bean)).replace(
1317: "$GETTER$",
1318: getGetterName(bean
1319: .getEntityClassInfo()
1320: .getIdFieldInfo()));
1321: }
1322:
1323: return bodyText;
1324: }
1325:
1326: private ClassTree addUpdateEntityMethod(WorkingCopy copy,
1327: ClassTree tree, EntityResourceBean bean) {
1328: Modifier[] modifiers = new Modifier[] { Modifier.PROTECTED };
1329: Object returnType = getEntityClassType(bean);
1330: String[] params = new String[] { "entity", "newEntity" };
1331: Object[] paramTypes = new Object[] { getEntityClassType(bean),
1332: getEntityClassType(bean) };
1333:
1334: String bodyText = "{ newEntity.$SETTER$(entity.$GETTER$();";
1335: bodyText = bodyText.replace("$SETTER$", getIdSetter(bean))
1336: .replace("$GETTER$", getIdGetter(bean));
1337:
1338: bodyText = bodyText + getRemoveOneToManyRelSubText(bean);
1339:
1340: bodyText = bodyText
1341: + "entity = PersistenceService.getInstance().mergeEntity(newEntity);";
1342:
1343: bodyText = bodyText + getUpdateOneToManyRelSubText(bean)
1344: + "return entity;}";
1345:
1346: String comment = "Updates entity using data from newEntity.\n\n"
1347: + "@param entity the entity to update\n"
1348: + "@param newEntity the entity containing the new data\n"
1349: + "@return the updated entity";
1350:
1351: return JavaSourceHelper.addMethod(copy, tree, modifiers, null,
1352: null, "updateEntity", returnType, params, paramTypes,
1353: null, null, bodyText, comment);
1354: }
1355:
1356: private String getRemoveOneToManyRelSubText(EntityResourceBean bean) {
1357: String template = "entity.$GETTER$().removeAll(newEntity.$GETTER$());"
1358: + "for ($CLASS$ value : entity.$GETTER$()) {"
1359: + "value.$SETTER$(null);" + "}";
1360:
1361: String bodyText = "";
1362:
1363: for (RelatedEntityResource subResource : bean.getSubResources()) {
1364: FieldInfo fieldInfo = subResource.getFieldInfo();
1365:
1366: if (fieldInfo.isOneToMany() || fieldInfo.isManyToMany()) {
1367: EntityResourceBean subBean = subResource
1368: .getResourceBean();
1369: EntityResourceBean itemResource = getItemSubResource(subBean);
1370:
1371: for (RelatedEntityResource subSubResource : itemResource
1372: .getSubResources()) {
1373: EntityResourceBean subSubBean = subSubResource
1374: .getResourceBean();
1375:
1376: if (bean == subSubBean) {
1377: bodyText = bodyText
1378: + template
1379: .replace(
1380: "$CLASS$",
1381: getEntityClassName(subBean))
1382: .replace(
1383: "$GETTER$",
1384: getGetterName(fieldInfo))
1385: .replace(
1386: "$SETTER$",
1387: getSetterName(subSubResource
1388: .getFieldInfo()));
1389: break;
1390: }
1391: }
1392: }
1393: }
1394:
1395: return bodyText;
1396: }
1397:
1398: private String getUpdateOneToManyRelSubText(EntityResourceBean bean) {
1399: String template = "for ($CLASS$ value : entity.$GETTER$()) {"
1400: + "value.$SETTER$(entity);" + "}";
1401:
1402: String bodyText = "";
1403:
1404: for (RelatedEntityResource subResource : bean.getSubResources()) {
1405: FieldInfo fieldInfo = subResource.getFieldInfo();
1406:
1407: if (fieldInfo.isOneToMany() || fieldInfo.isManyToMany()) {
1408: EntityResourceBean subBean = subResource
1409: .getResourceBean();
1410: EntityResourceBean itemResource = getItemSubResource(subBean);
1411:
1412: for (RelatedEntityResource subSubResource : itemResource
1413: .getSubResources()) {
1414: EntityResourceBean subSubBean = subSubResource
1415: .getResourceBean();
1416:
1417: if (bean == subSubBean) {
1418: bodyText = bodyText
1419: + template
1420: .replace(
1421: "$CLASS$",
1422: getEntityClassName(subBean))
1423: .replace(
1424: "$GETTER$",
1425: getGetterName(fieldInfo))
1426: .replace(
1427: "$SETTER$",
1428: getSetterName(subSubResource
1429: .getFieldInfo()));
1430: break;
1431: }
1432: }
1433: }
1434: }
1435:
1436: return bodyText;
1437: }
1438:
1439: private ClassTree addConverterFields(WorkingCopy copy,
1440: ClassTree tree, EntityResourceBean bean,
1441: boolean isRefConverter) {
1442: Modifier[] modifiers = new Modifier[] { Modifier.PRIVATE };
1443: ClassTree modifiedTree = tree;
1444:
1445: modifiedTree = JavaSourceHelper.addField(copy, modifiedTree,
1446: modifiers, null, null, "uri", Constants.URI_TYPE);
1447:
1448: if (bean.isItem()) {
1449: if (isRefConverter) {
1450: modifiedTree = JavaSourceHelper.addField(copy,
1451: modifiedTree, modifiers, null, null,
1452: "isUriExtendable", "boolean");
1453: }
1454: modifiedTree = JavaSourceHelper.addField(copy,
1455: modifiedTree, modifiers, null, null, "entity",
1456: getEntityClassType(bean));
1457: } else {
1458: Tree typeTree = JavaSourceHelper
1459: .createParameterizedTypeTree(copy,
1460: Constants.COLLECTION_TYPE,
1461: new String[] { getRefConverterType(bean) });
1462:
1463: modifiedTree = JavaSourceHelper.addField(copy,
1464: modifiedTree, modifiers, null, null, "references",
1465: typeTree);
1466:
1467: typeTree = JavaSourceHelper.createParameterizedTypeTree(
1468: copy, Constants.COLLECTION_TYPE,
1469: new String[] { getEntityClassType(bean) });
1470:
1471: modifiedTree = JavaSourceHelper.addField(copy,
1472: modifiedTree, modifiers, null, null, "entities",
1473: typeTree);
1474: }
1475:
1476: return modifiedTree;
1477: }
1478:
1479: private ClassTree addConverterConstructor(WorkingCopy copy,
1480: ClassTree tree, EntityResourceBean bean,
1481: boolean isRefConverter) {
1482: String[] parameters = null;
1483: Object[] types = null;
1484: String bodyText = null;
1485: String comment = null;
1486:
1487: if (bean.isItem()) {
1488: types = new String[] { getEntityClassType(bean),
1489: Constants.URI_TYPE, "boolean" };
1490:
1491: if (isRefConverter) {
1492: parameters = new String[] { "entity", "uri",
1493: "isUriExtendable" };
1494: bodyText = "{this.entity = entity; this.uri = uri;"
1495: + "this.isUriExtendable = isUriExtendable;}";
1496:
1497: comment = "Creates a new instance of $CONVERTER$.\n\n"
1498: + "@param entity associated entity\n"
1499: + "@param uri associated uri\n"
1500: + "@param isUriExtendable indicates whether the uri can be extended";
1501: comment = comment.replace("$CONVERTER$",
1502: getRefConverterName(bean));
1503: } else {
1504: parameters = new String[] { "entity", "uri" };
1505: bodyText = "{this.entity = entity; this.uri = uri;}";
1506:
1507: comment = "Creates a new instance of $CONVERTER$.\n\n"
1508: + "@param entity associated entity\n"
1509: + "@param uri associated uri";
1510: comment = comment.replace("$CONVERTER$",
1511: getConverterName(bean));
1512: }
1513: } else {
1514: parameters = new String[] { "entities", "uri" };
1515: Tree typeTree = JavaSourceHelper
1516: .createParameterizedTypeTree(copy,
1517: Constants.COLLECTION_TYPE,
1518: new String[] { getEntityClassType(bean) });
1519: types = new Object[] { typeTree, Constants.URI_TYPE };
1520: bodyText = "{this.entities = entities; this.uri = uri;}";
1521:
1522: comment = "Creates a new instance of $CONVERTER$.\n\n"
1523: + "@param entities associated entities\n"
1524: + "@param uri associated uri";
1525: comment = comment.replace("$CONVERTER$",
1526: getConverterName(bean));
1527: }
1528:
1529: return JavaSourceHelper.addConstructor(copy, tree,
1530: new Modifier[] { Modifier.PUBLIC }, parameters, types,
1531: bodyText, comment);
1532: }
1533:
1534: private ClassTree addGetReferencesMethod(WorkingCopy copy,
1535: ClassTree tree, EntityResourceBean bean) {
1536: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1537: String[] annotations = new String[] { Constants.XML_ELEMENT_ANNOTATION };
1538: Object[] annotationAttrs = new Object[] { JavaSourceHelper
1539: .createAssignmentTree(copy, "name",
1540: getRefConverterXMLName(bean)) };
1541:
1542: Object returnType = JavaSourceHelper
1543: .createParameterizedTypeTree(copy,
1544: Constants.COLLECTION_TYPE,
1545: new String[] { getRefConverterType(bean) });
1546:
1547: String bodyText = "{ "
1548: + "references = new ArrayList<$REF_CONVERTER$>();"
1549: + "if (entities != null) {"
1550: + "for ($CLASS$ entity : entities) {"
1551: + "references.add(new $REF_CONVERTER$(entity, uri, true));"
1552: + "}" + "}" + "return references;" + "}";
1553:
1554: bodyText = bodyText
1555: .replace("$CLASS$", getEntityClassName(bean)).replace(
1556: "$REF_CONVERTER$", getRefConverterName(bean));
1557:
1558: String comment = "Returns a collection of $REF_CONVERTER$.\n\n"
1559: + "@return a collection of $REF_CONVERTER$";
1560: comment = comment.replace("$REF_CONVERTER$",
1561: getRefConverterName(bean));
1562:
1563: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1564: annotations, annotationAttrs, "getReferences",
1565: returnType, null, null, null, null, bodyText, comment);
1566: }
1567:
1568: private ClassTree addSetReferencesMethod(WorkingCopy copy,
1569: ClassTree tree, EntityResourceBean bean) {
1570: String[] args = new String[] { "references" };
1571: String refClassName = getRefConverterType(bean);
1572: Object argType = JavaSourceHelper.createParameterizedTypeTree(
1573: copy, Constants.COLLECTION_TYPE,
1574: new String[] { refClassName });
1575:
1576: String bodyText = "{this.references = references;}";
1577:
1578: String comment = "Sets a collection of $REF_CONVERTER$.\n\n"
1579: + "@param a collection of $REF_CONVERTER$ to set";
1580: comment = comment.replace("$REF_CONVERTER$",
1581: getRefConverterName(bean));
1582:
1583: return JavaSourceHelper
1584: .addMethod(copy, tree, Constants.PUBLIC, null, null,
1585: "setReferences", Constants.VOID, args,
1586: new Object[] { argType }, null, null, bodyText,
1587: comment);
1588: }
1589:
1590: private ClassTree addGetUriMethod(WorkingCopy copy, ClassTree tree) {
1591: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1592: String[] annotations = new String[] { Constants.XML_ATTRIBUTE_ANNOTATION };
1593: Object[] annotationAttrs = new Object[] { JavaSourceHelper
1594: .createAssignmentTree(copy, "name", "uri") };
1595:
1596: Object returnType = Constants.URI_TYPE;
1597:
1598: String bodyText = "{return uri;}";
1599:
1600: String comment = "Returns the URI associated with this converter.\n\n"
1601: + "@return the uri";
1602:
1603: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1604: annotations, annotationAttrs, "getResourceUri",
1605: returnType, null, null, null, null, bodyText, comment);
1606: }
1607:
1608: private ClassTree addContainerConverterGetEntitiesMethod(
1609: WorkingCopy copy, ClassTree tree, EntityResourceBean bean) {
1610: String[] annotations = new String[] { Constants.XML_TRANSIENT_ANNOTATION };
1611: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1612: Tree returnType = JavaSourceHelper.createParameterizedTypeTree(
1613: copy, Constants.COLLECTION_TYPE,
1614: new String[] { getEntityClassType(bean) });
1615:
1616: String bodyText = "{ entities = new ArrayList<$CLASS$>();"
1617: + "if (references != null) { "
1618: + "for ($REFCLASS$ ref : references) {"
1619: + "entities.add(ref.getEntity()); } " + "}"
1620: + "return entities;" + "}";
1621:
1622: bodyText = bodyText
1623: .replace("$CLASS$", getEntityClassName(bean)).replace(
1624: "$REFCLASS$", getRefConverterName(bean));
1625:
1626: String comment = "Returns a collection $CLASS$ entities.\n\n"
1627: + "@return a collection of $CLASS$ entities";
1628: comment = comment.replace("$CLASS$", getEntityClassName(bean));
1629:
1630: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1631: annotations, null, "getEntities", returnType, null,
1632: null, null, null, bodyText, comment);
1633: }
1634:
1635: private ClassTree addGetterMethod(WorkingCopy copy, ClassTree tree,
1636: FieldInfo fieldInfo) {
1637: String getterName = getGetterName(fieldInfo);
1638: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1639: String[] annotations = new String[] { Constants.XML_ELEMENT_ANNOTATION };
1640: Object[] annotationAttrs = null;
1641: Object returnType = null;
1642: String bodyText = null;
1643:
1644: if (!fieldInfo.isRelationship()) {
1645: if (fieldInfo.getTypeArg() == null) {
1646: returnType = fieldInfo.getType();
1647: } else {
1648: returnType = JavaSourceHelper
1649: .createParameterizedTypeTree(copy, fieldInfo
1650: .getType(), new String[] { fieldInfo
1651: .getTypeArg() });
1652: }
1653:
1654: bodyText = "{return entity.$GETTER$();}";
1655: bodyText = bodyText.replace("$GETTER$", getterName);
1656: } else {
1657: if (fieldInfo.isOneToMany() || fieldInfo.isManyToMany()) {
1658: EntityResourceBean foreignBean = model
1659: .getContainerResourceBean(fieldInfo
1660: .getTypeArg());
1661: annotationAttrs = new Object[] { JavaSourceHelper
1662: .createAssignmentTree(copy, "name",
1663: lowerCaseFirstLetter(foreignBean
1664: .getName())) };
1665: returnType = getConverterType(foreignBean);
1666:
1667: bodyText = "{if (entity.$GETTER$() != null)"
1668: + "{return new $CONVERTER$(entity.$GETTER$(), uri.resolve(\"$FIELD$/\"));}"
1669: + " return null;}";
1670: bodyText = bodyText.replace("$CONVERTER$",
1671: getConverterName(foreignBean)).replace(
1672: "$GETTER$", getGetterName(fieldInfo)).replace(
1673: "$FIELD$",
1674: lowerCaseFirstLetter(foreignBean.getName()));
1675: } else { // should be 1-1 or n-1
1676: EntityResourceBean foreignBean = model
1677: .getItemResourceBean(fieldInfo.getType());
1678: annotationAttrs = new Object[] { JavaSourceHelper
1679: .createAssignmentTree(copy, "name",
1680: getRefConverterXMLName(foreignBean)) };
1681: returnType = getRefConverterType(foreignBean);
1682:
1683: bodyText = "{if (entity.$GETTER$() != null)"
1684: + "{return new $REF_CONVERTER$(entity.$GETTER$(), uri.resolve(\"$FIELD$/\"), false);}"
1685: + "return null;}";
1686: bodyText = bodyText.replace("$REF_CONVERTER$",
1687: getRefConverterName(foreignBean)).replace(
1688: "$GETTER$", getGetterName(fieldInfo)).replace(
1689: "$FIELD$",
1690: lowerCaseFirstLetter(foreignBean.getName()));
1691: }
1692: }
1693:
1694: String comment = "Getter for $FIELD$.\n\n"
1695: + "@return value for $FIELD$";
1696: comment = comment.replace("$FIELD$", fieldInfo.getName());
1697:
1698: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1699: annotations, annotationAttrs, getterName, returnType,
1700: null, null, null, null, bodyText, comment);
1701: }
1702:
1703: private ClassTree addSetterMethod(WorkingCopy copy, ClassTree tree,
1704: FieldInfo fieldInfo, EntityResourceBean bean) {
1705: String setterName = getSetterName(fieldInfo);
1706: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1707: String[] annotations = null;
1708: Object[] annotationAttrs = null;
1709: String[] args = new String[] { "value" };
1710: Object argType = null;
1711: String bodyText = null;
1712:
1713: if (!fieldInfo.isRelationship()) {
1714: if (fieldInfo.getTypeArg() == null) {
1715: argType = fieldInfo.getType();
1716: } else {
1717: argType = JavaSourceHelper.createParameterizedTypeTree(
1718: copy, fieldInfo.getType(),
1719: new String[] { fieldInfo.getTypeArg() });
1720: }
1721:
1722: bodyText = "{ entity.$SETTER$(value); }";
1723: bodyText = bodyText.replace("$SETTER$", setterName)
1724: .replace("$CLASS$", getEntityClassName(bean));
1725: } else {
1726: if (fieldInfo.isOneToMany() || fieldInfo.isManyToMany()) {
1727: EntityResourceBean foreignBean = model
1728: .getContainerResourceBean(fieldInfo
1729: .getTypeArg());
1730: String relatedEntityName = model.getItemResourceBean(
1731: fieldInfo.getTypeArg()).getName();
1732: argType = getConverterType(foreignBean);
1733: bodyText = "{ if (value != null) {"
1734: + "entity.$SETTER$(value.getEntities());" + "}"
1735: + "}";
1736:
1737: bodyText = bodyText.replace("$CLASS$",
1738: relatedEntityName).replace("$SETTER$",
1739: setterName);
1740: } else { // should be 1-1
1741: EntityResourceBean foreignBean = model
1742: .getItemResourceBean(fieldInfo.getType());
1743: argType = getRefConverterType(foreignBean);
1744:
1745: bodyText = "{ if (value != null) {"
1746: + "entity.$SETTER$(value.getEntity()); " + "}"
1747: + "}";
1748:
1749: bodyText = bodyText.replace("$CLASS$",
1750: foreignBean.getName()).replace("$SETTER$",
1751: setterName);
1752: }
1753: }
1754:
1755: String comment = "Setter for $FIELD$.\n\n"
1756: + "@param value the value to set";
1757: comment = comment.replace("$FIELD$", fieldInfo.getName());
1758:
1759: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1760: annotations, annotationAttrs, setterName,
1761: Constants.VOID, args, new Object[] { argType }, null,
1762: null, bodyText, comment);
1763: }
1764:
1765: private ClassTree addItemConverterGetEntityMethod(WorkingCopy copy,
1766: ClassTree tree, EntityResourceBean bean) {
1767: String[] annotations = new String[] { Constants.XML_TRANSIENT_ANNOTATION };
1768: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1769:
1770: String bodyText = "{ return entity; }";
1771:
1772: String comment = "Returns the $CLASS$ entity.\n\n"
1773: + "@return an entity";
1774: comment = comment.replace("$CLASS$", getEntityClassName(bean));
1775:
1776: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1777: annotations, null, "getEntity",
1778: getEntityClassType(bean), null, null, null, null,
1779: bodyText, comment);
1780: }
1781:
1782: private ClassTree addItemConverterSetEntityMethod(WorkingCopy copy,
1783: ClassTree tree, EntityResourceBean bean) {
1784: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1785: String[] params = new String[] { "entity" };
1786: Object[] paramTypes = new Object[] { getEntityClassName(bean) };
1787: String bodyText = "{ this.entity = entity; }";
1788:
1789: String comment = "Sets the $CLASS$ entity.\n\n"
1790: + "@param entity to set";
1791: comment = comment.replace("$CLASS$", getEntityClassName(bean));
1792:
1793: return JavaSourceHelper.addMethod(copy, tree, modifiers, null,
1794: null, "setEntity", Constants.VOID, params, paramTypes,
1795: null, null, bodyText, comment);
1796: }
1797:
1798: private ClassTree addGetUriMethod(WorkingCopy copy, ClassTree tree,
1799: FieldInfo fieldInfo) {
1800: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1801: String[] annotations = new String[] { Constants.XML_ATTRIBUTE_ANNOTATION };
1802: Object[] annotationAttrs = new Object[] { JavaSourceHelper
1803: .createAssignmentTree(copy, "name", "uri") };
1804:
1805: Object returnType = Constants.URI_TYPE;
1806:
1807: String bodyText = "{if (isUriExtendable) {"
1808: + "return uri.resolve($ID_TO_URI$ + \"/\");" + "}"
1809: + "return uri;" + "}";
1810:
1811: bodyText = bodyText.replace("$ID_TO_URI$",
1812: getIdFieldToUriStmt(fieldInfo));
1813:
1814: String comment = "Returns the URI associated with this reference converter.\n\n"
1815: + "@return the converted uri";
1816:
1817: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1818: annotations, annotationAttrs, "getResourceUri",
1819: returnType, null, null, null, null, bodyText, comment);
1820: }
1821:
1822: private ClassTree addSetUriMethod(WorkingCopy copy, ClassTree tree,
1823: FieldInfo fieldInfo) {
1824: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1825: Object returnType = Constants.VOID;
1826: String[] params = new String[] { "uri" }; //NOI18N
1827: Object[] paramTypes = new Object[] { Constants.URI_TYPE };
1828:
1829: String bodyText = "{ this.uri = uri; }"; //NOI18N
1830:
1831: String comment = "Sets the URI for this reference converter.\n\n";
1832:
1833: return JavaSourceHelper.addMethod(copy, tree, modifiers, null,
1834: null, "setResourceUri", returnType, params, paramTypes,
1835: null, null, bodyText, comment);
1836: }
1837:
1838: private ClassTree addRefConverterGetEntityMethod(WorkingCopy copy,
1839: ClassTree tree, EntityResourceBean bean) {
1840: String[] annotations = new String[] { Constants.XML_TRANSIENT_ANNOTATION };
1841: Modifier[] modifiers = new Modifier[] { Modifier.PUBLIC };
1842:
1843: String bodyText = "{ "
1844: + "$CONVERTER$ result = UriResolver.getInstance().resolve($CONVERTER$.class, uri);"
1845: + "if (result != null) {"
1846: + "return result.getEntity();" + "}" + "return null;"
1847: + "}";
1848:
1849: bodyText = bodyText.replace("$CONVERTER$",
1850: getConverterName(bean));
1851:
1852: String comment = "Returns the $CLASS$ entity.\n\n"
1853: + "@return $CLASS$ entity";
1854: comment = comment.replace("$CLASS$", getEntityClassName(bean));
1855:
1856: return JavaSourceHelper.addMethod(copy, tree, modifiers,
1857: annotations, null, "getEntity",
1858: getEntityClassType(bean), null, null, null, null,
1859: bodyText, comment);
1860: }
1861:
1862: private EntityResourceBean getItemSubResource(
1863: EntityResourceBean containerResource) {
1864: Collection<RelatedEntityResource> subResources = containerResource
1865: .getSubResources();
1866:
1867: return subResources.iterator().next().getResourceBean();
1868: }
1869:
1870: private String getResourcePackageName() {
1871: return resourcePackageName;
1872: }
1873:
1874: private String getConverterPackageName() {
1875: return converterPackageName;
1876: }
1877:
1878: private String getResourceName(EntityResourceBean bean) {
1879: return bean.getName() + RESOURCE_SUFFIX;
1880: }
1881:
1882: private String getItemResourceName(EntityResourceBean bean) {
1883: return Util.getSingularName(bean) + RESOURCE_SUFFIX;
1884: }
1885:
1886: private String getConverterName(EntityResourceBean bean) {
1887: return bean.getName() + CONVERTER_SUFFIX;
1888: }
1889:
1890: private String getItemConverterName(EntityResourceBean bean) {
1891: return Util.getSingularName(bean) + CONVERTER_SUFFIX;
1892: }
1893:
1894: private String getRefConverterName(EntityResourceBean bean) {
1895: return Util.getSingularName(bean) + REF_CONVERTER_SUFFIX;
1896: }
1897:
1898: private String getConverterXMLName(EntityResourceBean bean) {
1899: return lowerCaseFirstLetter(bean.getName());
1900: }
1901:
1902: private String getRefConverterXMLName(EntityResourceBean bean) {
1903: return lowerCaseFirstLetter(Util.getSingularName(bean)
1904: + REF_SUFFIX);
1905: }
1906:
1907: private String getRefConverterType(EntityResourceBean bean) {
1908: return getConverterPackageName() + "." + //NOI18N
1909: getRefConverterName(bean);
1910: }
1911:
1912: private String getConverterType(EntityResourceBean bean) {
1913: return getConverterPackageName() + "." + //NOI18N
1914: bean.getName() + CONVERTER_SUFFIX;
1915: }
1916:
1917: private String getResourceType(EntityResourceBean bean) {
1918: return getResourcePackageName() + "." + //NOI18N
1919: bean.getName() + RESOURCE_SUFFIX;
1920: }
1921:
1922: private String getGetterName(FieldInfo fieldInfo) {
1923: return "get" + capitalizeFirstLetter(fieldInfo.getName()); //NOI18N
1924: }
1925:
1926: private String getSetterName(FieldInfo fieldInfo) {
1927: return "set" + capitalizeFirstLetter(fieldInfo.getName()); //NOI18N
1928: }
1929:
1930: private String getIdFieldType(EntityResourceBean bean) {
1931: String type = bean.getEntityClassInfo().getIdFieldInfo()
1932: .getType();
1933:
1934: // Temporary workaround because Jersey does not support
1935: // Character type in UriParam
1936: if (type.equals("java.lang.Character")) { //NOI18N
1937: return "java.lang.String"; //NOI18N
1938: }
1939:
1940: return type;
1941: }
1942:
1943: private String getIdFieldName(EntityResourceBean bean) {
1944: return bean.getEntityClassInfo().getIdFieldInfo().getName();
1945: }
1946:
1947: private String[] getIdFieldIdArray(EntityResourceBean bean,
1948: boolean append, String additionalId) {
1949: FieldInfo field = bean.getEntityClassInfo().getIdFieldInfo();
1950:
1951: if (field.isEmbeddedId()) {
1952: Collection<FieldInfo> fields = field.getFieldInfos();
1953: int index = 0;
1954: int size = (append) ? fields.size() + 1 : fields.size();
1955: String[] idArray = new String[size];
1956:
1957: for (int i = 0; i < size; i++) {
1958: idArray[i] = "id" + (i + 1);
1959: }
1960: if (append) {
1961: idArray[size - 1] = additionalId;
1962: }
1963:
1964: return idArray;
1965: } else {
1966: if (!append) {
1967: return new String[] { "id" };
1968: } else {
1969: return new String[] { "id", additionalId };
1970: }
1971: }
1972: }
1973:
1974: private String[] getIdFieldNameArray(EntityResourceBean bean,
1975: boolean append, String additionalName) {
1976: FieldInfo field = bean.getEntityClassInfo().getIdFieldInfo();
1977:
1978: if (field.isEmbeddedId()) {
1979: Collection<FieldInfo> fields = field.getFieldInfos();
1980: int index = 0;
1981: int size = (append) ? fields.size() + 1 : fields.size();
1982: String[] fieldArray = new String[size];
1983:
1984: for (FieldInfo f : fields) {
1985: fieldArray[index++] = f.getName();
1986: }
1987:
1988: if (append) {
1989: fieldArray[size - 1] = additionalName;
1990: }
1991:
1992: return fieldArray;
1993: } else {
1994: if (!append) {
1995: return new String[] { field.getName() };
1996: } else {
1997: return new String[] { field.getName(), additionalName };
1998: }
1999: }
2000: }
2001:
2002: private Object[] getIdFieldTypeArray(EntityResourceBean bean,
2003: boolean append, Object additionalType) {
2004: FieldInfo field = bean.getEntityClassInfo().getIdFieldInfo();
2005:
2006: if (field.isEmbeddedId()) {
2007: Collection<FieldInfo> fields = field.getFieldInfos();
2008: int index = 0;
2009: int size = (append) ? fields.size() + 1 : fields.size();
2010: Object[] typeArray = new Object[size];
2011:
2012: for (FieldInfo f : fields) {
2013: typeArray[index++] = f.getType();
2014: }
2015:
2016: if (append) {
2017: typeArray[size - 1] = additionalType;
2018: }
2019: return typeArray;
2020: } else {
2021: String type = field.getType();
2022: if (type.equals("java.lang.Character")) {
2023: type = "java.lang.String";
2024: }
2025:
2026: if (!append) {
2027: return new Object[] { type };
2028: } else {
2029: return new Object[] { type, additionalType };
2030: }
2031: }
2032: }
2033:
2034: private String[] getIdFieldUriParamArray(EntityResourceBean bean,
2035: boolean append, String additionalUriParam) {
2036: FieldInfo field = bean.getEntityClassInfo().getIdFieldInfo();
2037:
2038: if (field.isEmbeddedId()) {
2039: int size = (append) ? field.getFieldInfos().size() + 1
2040: : field.getFieldInfos().size();
2041: String[] uriParamArray = new String[size];
2042:
2043: for (int i = 0; i < size; i++) {
2044: uriParamArray[i] = RestConstants.URI_PARAM_ANNOTATION;
2045: }
2046:
2047: if (append) {
2048: uriParamArray[size - 1] = additionalUriParam;
2049: }
2050:
2051: return uriParamArray;
2052: } else {
2053: if (!append) {
2054: return new String[] { RestConstants.URI_PARAM_ANNOTATION };
2055: } else {
2056: return new String[] {
2057: RestConstants.URI_PARAM_ANNOTATION,
2058: additionalUriParam };
2059: }
2060: }
2061: }
2062:
2063: private String getIdFieldIdList(EntityResourceBean bean) {
2064: FieldInfo field = bean.getEntityClassInfo().getIdFieldInfo();
2065:
2066: if (field.isEmbeddedId()) {
2067: int size = field.getFieldInfos().size();
2068: String idList = "";
2069:
2070: for (int i = 1; i <= size; i++) {
2071: if (i > 1) {
2072: idList += ", ";
2073: }
2074:
2075: idList += "id" + i;
2076: }
2077:
2078: return idList;
2079: } else {
2080: return "id"; //NOI18N
2081: }
2082: }
2083:
2084: private String getIdFieldToUriStmt(EntityResourceBean bean) {
2085: return getIdFieldToUriStmt(bean.getEntityClassInfo()
2086: .getIdFieldInfo());
2087: }
2088:
2089: private String getIdFieldToUriStmt(FieldInfo idField) {
2090: String getterName = getGetterName(idField);
2091:
2092: if (idField.isEmbeddedId()) {
2093: Collection<FieldInfo> fields = idField.getFieldInfos();
2094: int size = fields.size();
2095: String stmt = "";
2096: int index = 0;
2097:
2098: for (FieldInfo f : fields) {
2099: if (index++ > 0) {
2100: stmt += " + \",\" + ";
2101: }
2102: stmt += "entity." + getterName + "()."
2103: + getGetterName(f) + "()";
2104: }
2105:
2106: return stmt;
2107: } else {
2108: return "entity." + getterName + "()";
2109: }
2110: }
2111:
2112: private String getIdFieldParamList(EntityResourceBean bean) {
2113: FieldInfo idField = bean.getEntityClassInfo().getIdFieldInfo();
2114:
2115: if (idField.isEmbeddedId()) {
2116: Collection<FieldInfo> fields = idField.getFieldInfos();
2117: int index = 0;
2118: int size = fields.size();
2119: String paramStr = "";
2120:
2121: for (FieldInfo f : fields) {
2122: if (index++ > 0) {
2123: paramStr += ", ";
2124: }
2125:
2126: paramStr += f.getSimpleTypeName() + " id" + index;
2127: }
2128:
2129: return paramStr;
2130: } else {
2131: String type = idField.getSimpleTypeName();
2132: if (type.equals("Character")) {
2133: type = "String";
2134: }
2135:
2136: return type + " id";
2137: }
2138: }
2139:
2140: private String getIdGetter(EntityResourceBean bean) {
2141: return getGetterName(bean.getEntityClassInfo().getIdFieldInfo());
2142: }
2143:
2144: private String getIdSetter(EntityResourceBean bean) {
2145: return getSetterName(bean.getEntityClassInfo().getIdFieldInfo());
2146: }
2147:
2148: private String getEntityClassName(EntityResourceBean bean) {
2149: return bean.getEntityClassInfo().getName();
2150: }
2151:
2152: private String getEntityClassType(EntityResourceBean bean) {
2153: return bean.getEntityClassInfo().getType();
2154: }
2155:
2156: private String getPersistenceServiceClassType() {
2157: return getResourcePackageName() + "." + PERSISTENCE_SERVICE;
2158: }
2159:
2160: private String getUriResolverClassType() {
2161: return getConverterPackageName() + "." + URI_RESOLVER;
2162: }
2163:
2164: private String capitalizeFirstLetter(String str) {
2165: return str.substring(0, 1).toUpperCase()
2166: + str.substring(1, str.length());
2167: }
2168:
2169: private String lowerCaseFirstLetter(String str) {
2170: return str.substring(0, 1).toLowerCase()
2171: + str.substring(1, str.length());
2172: }
2173:
2174: private String demodulize(String str) {
2175: return Inflector.getInstance().demodulize(str);
2176: }
2177:
2178: protected int getTotalWorkUnits() {
2179: int totalUnits = 0;
2180:
2181: for (EntityResourceBean bean : model.getResourceBeans()) {
2182: totalUnits += 2;
2183:
2184: if (bean.isItem()) {
2185: totalUnits++;
2186: }
2187: }
2188:
2189: totalUnits = (totalUnits + 2) * 2;
2190:
2191: return totalUnits;
2192: }
2193:
2194: private void reportProgress(String className, boolean modifying) {
2195: String message = null;
2196:
2197: if (!modifying) {
2198: message = NbBundle.getMessage(
2199: EntityResourcesGenerator.class,
2200: "MSG_CreatingClass", className);
2201: } else {
2202: message = NbBundle.getMessage(
2203: EntityResourcesGenerator.class,
2204: "MSG_ModifyingClass", className);
2205: }
2206:
2207: reportProgress(message);
2208: }
2209: }
|