| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.netbeans.modules.websvc.rest.codegen; |
| |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Set; |
| |
| import javax.lang.model.element.Modifier; |
| |
| import org.netbeans.api.java.source.JavaSource; |
| import org.netbeans.api.java.source.JavaSource.Phase; |
| import org.netbeans.api.java.source.Task; |
| import org.netbeans.api.java.source.TreeMaker; |
| import org.netbeans.api.java.source.WorkingCopy; |
| import org.netbeans.modules.j2ee.core.api.support.java.GenerationUtils; |
| import org.netbeans.modules.j2ee.core.api.support.java.JavaIdentifiers; |
| import org.netbeans.modules.websvc.rest.codegen.model.EntityClassInfo; |
| import org.netbeans.modules.websvc.rest.codegen.model.EntityClassInfo.FieldInfo; |
| import org.netbeans.modules.websvc.rest.model.api.RestConstants; |
| import org.netbeans.modules.websvc.rest.support.JavaSourceHelper; |
| import org.netbeans.modules.websvc.rest.support.SpringHelper; |
| import org.openide.filesystems.FileObject; |
| |
| import com.sun.source.tree.ClassTree; |
| import com.sun.source.tree.CompilationUnitTree; |
| import com.sun.source.tree.ModifiersTree; |
| |
| /** |
| * |
| * @author ads |
| */ |
| public class SpringEntityResourcesGenerator extends EntityResourcesGenerator { |
| |
| SpringEntityResourcesGenerator( boolean hasAopAlliance ){ |
| this.hasAopAlliance = hasAopAlliance; |
| } |
| |
| @Override |
| protected void configurePersistence() { |
| new SpringHelper(getProject(), getPersistenceUnit()).configure(); |
| } |
| |
| @Override |
| protected void createFolders() { |
| createFolders( false ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.netbeans.modules.websvc.rest.codegen.EntityResourcesGenerator#generateInfrastracture(java.util.Set, java.lang.String, org.openide.filesystems.FileObject) |
| */ |
| @Override |
| protected boolean generateInfrastracture( Set<FileObject> createdFiles, |
| String entityFqn, FileObject facade ) throws IOException |
| { |
| if ( !super.generateInfrastracture(createdFiles, entityFqn, facade) ){ |
| return false; |
| } |
| |
| // Inject EntityManager |
| JavaSource javaSource = JavaSource.forFileObject( facade ); |
| if ( javaSource == null ){ |
| return false; |
| } |
| Task<WorkingCopy> task = new Task<WorkingCopy>() { |
| |
| @Override |
| public void run(WorkingCopy workingCopy) throws Exception { |
| workingCopy.toPhase(Phase.RESOLVED); |
| CompilationUnitTree tree = workingCopy.getCompilationUnit(); |
| |
| |
| String[] annotations ; |
| Object[] values ; |
| if ( hasAopAlliance ){ |
| annotations = new String[]{Constants.PERSISTENCE_CONTEXT_ANNOTATION}; |
| values = new Object[]{JavaSourceHelper.createAssignmentTree( |
| workingCopy, "unitName", // NOI18N |
| getPersistenceUnit().getName())}; |
| } |
| else { |
| annotations = new String[]{Constants.PERSISTENCE_CONTEXT_ANNOTATION, |
| "Error"}; // NOI18N |
| values = new Object[]{JavaSourceHelper.createAssignmentTree( |
| workingCopy, "unitName", // NOI18N |
| getPersistenceUnit().getName()), |
| "Please fix your project manually, for instructions see " + |
| "http://wiki.netbeans.org/SpringWithAopalliance" // NOI18N |
| }; |
| } |
| |
| ClassTree classTree = (ClassTree)tree.getTypeDecls().get(0); |
| ClassTree newTree = JavaSourceHelper.addField(workingCopy, classTree, |
| new Modifier[]{Modifier.PROTECTED}, |
| annotations , values , "entityManager", |
| Constants.ENTITY_MANAGER_TYPE); //NOI18N |
| workingCopy.rewrite(classTree, newTree); |
| } |
| }; |
| javaSource.runModificationTask(task).commit(); |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.netbeans.modules.websvc.rest.codegen.EntityResourcesGenerator#getRestFacadeMethodOptions(java.lang.String, java.lang.String) |
| */ |
| @Override |
| protected List<RestGenerationOptions> getRestFacadeMethodOptions( |
| String entityFQN, String idClass ) |
| { |
| List<RestGenerationOptions> original = super.getRestFacadeMethodOptions( |
| entityFQN, idClass); |
| List<RestGenerationOptions> result = new ArrayList<RestGenerationOptions>( |
| original.size() + 1); |
| result.addAll( original ); |
| RestGenerationOptions option = new RestGenerationOptions(); |
| RestMethod method = new FindMethod(); |
| option.setRestMethod(method); |
| option.setParameterNames(new String[]{"all", "maxResults", "firstResult"});// NOI18N |
| option.setParameterTypes(new String[]{"boolean" , "int", "int"}); // NOI18N |
| StringBuilder returnType = new StringBuilder(List.class.getCanonicalName()); |
| returnType.append('<'); |
| returnType.append(JavaIdentifiers.unqualify(entityFQN)); |
| returnType.append('>'); |
| option.setReturnType(returnType.toString()); |
| StringBuilder body = new StringBuilder("try { "); // NOI18N |
| body.append("Query query = entityManager.createQuery("); // NOI18N |
| body.append('"'); |
| body.append("SELECT object(o) FROM "); // NOI18N |
| body.append(getModel().getEntityInfo(entityFQN).getName()); |
| body.append(" AS o\");"); // NOI18N |
| body.append("if (!all) {"); // NOI18N |
| body.append(" query.setMaxResults(maxResults);"); // NOI18N |
| body.append(" query.setFirstResult(firstResult);}"); // NOI18N |
| body.append(" return query.getResultList();"); // NOI18N |
| body.append("} finally { entityManager.close();}"); // NOI18N |
| option.setBody(body.toString()); |
| result.add(option); |
| return result ; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.netbeans.modules.websvc.rest.codegen.EntityResourcesGenerator#addRestMethodAnnotations(org.netbeans.modules.j2ee.core.api.support.java.GenerationUtils, org.netbeans.api.java.source.TreeMaker, org.netbeans.modules.websvc.rest.codegen.RestGenerationOptions, com.sun.source.tree.ModifiersTree) |
| */ |
| @Override |
| protected ModifiersTree addRestMethodAnnotations( GenerationUtils genUtils, |
| TreeMaker maker, RestGenerationOptions option, |
| ModifiersTree modifiers ) |
| { |
| ModifiersTree tree = super.addRestMethodAnnotations(genUtils, maker, |
| option, modifiers); |
| if ( option.getRestMethod().getMethod() != null ){ |
| tree = maker.addModifiersAnnotation(tree, genUtils.createAnnotation( |
| SpringConstants.TRANSACTIONAL)); |
| } |
| return tree; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.netbeans.modules.websvc.rest.codegen.EntityResourcesGenerator#getResourceImports(java.lang.String) |
| */ |
| @Override |
| protected List<String> getResourceImports( String entityFqn ) { |
| List<String> original = super.getResourceImports(entityFqn); |
| List<String> result = new ArrayList<String>( original.size() +1 ); |
| result.addAll( original ); |
| result.add("javax.persistence.Query"); // NOI18N |
| result.add(Constants.PERSISTENCE_CONTEXT); |
| return result; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.netbeans.modules.websvc.rest.codegen.EntityResourcesGenerator#addResourceAnnotation(java.lang.String, com.sun.source.tree.ClassTree, org.netbeans.modules.j2ee.core.api.support.java.GenerationUtils, org.netbeans.api.java.source.TreeMaker) |
| */ |
| @Override |
| protected ModifiersTree addResourceAnnotation( String entityFQN, |
| ClassTree classTree, GenerationUtils genUtils, TreeMaker maker ) |
| { |
| ModifiersTree tree = super.addResourceAnnotation(entityFQN, classTree, |
| genUtils, maker); |
| |
| tree = maker.addModifiersAnnotation( tree, genUtils.createAnnotation( |
| RestConstants.SINGLETON)); |
| tree = maker.addModifiersAnnotation( tree, genUtils.createAnnotation( |
| SpringConstants.AUTOWIRE)); |
| return tree; |
| } |
| |
| @Override |
| protected RestGenerationOptions getGenerationOptions( |
| RestFacadeMethod method, String entityFQN, String paramArg, |
| String idType ) |
| { |
| String entitySimpleName = JavaIdentifiers.unqualify(entityFQN); |
| RestGenerationOptions options = super.getGenerationOptions(method, |
| entityFQN, paramArg, idType); |
| boolean needPathSegment = false; |
| EntityClassInfo entityInfo = getModel().getEntityInfo(entityFQN); |
| if ( entityInfo!= null ){ |
| FieldInfo idFieldInfo = entityInfo.getIdFieldInfo(); |
| needPathSegment = idFieldInfo!= null && idFieldInfo.isEmbeddedId()&& |
| idFieldInfo.getType()!= null; |
| } |
| StringBuilder builder ; |
| switch ( method ){ |
| case CREATE: |
| builder = new StringBuilder("entityManager.persist(entity);"); // NOI18N |
| builder.append("return Response.created("); // NOI18N |
| builder.append("URI.create("); // NOI18N |
| builder.append(getIdFieldToUriStmt(getModel().getEntityInfo(entityFQN). |
| getIdFieldInfo())); |
| builder.append(".toString())).build();"); // NOI18N |
| options.setBody(builder.toString()); |
| return options; |
| case EDIT: |
| options.setReturnType("void"); // NOI18N |
| builder = new StringBuilder("entityManager.merge(entity);"); // NOI18N |
| options.setBody(builder.toString()); |
| return options; |
| case REMOVE: |
| options.setReturnType("void"); // NOI18N |
| builder = new StringBuilder(); |
| if ( needPathSegment ){ |
| builder.append(idType); |
| builder.append( " key=getPrimaryKey(id);\n"); // NOI18N |
| paramArg = "key"; // NOI18N |
| } |
| builder.append(entitySimpleName); |
| builder.append(" entity = entityManager.getReference("); // NOI18N |
| builder.append(entitySimpleName); |
| builder.append(".class, "); // NOI18N |
| builder.append(paramArg); |
| builder.append(");"); // NOI18N |
| builder.append("entityManager.remove(entity);"); // NOI18N |
| options.setBody(builder.toString()); |
| return options; |
| case FIND: |
| builder = new StringBuilder(); |
| if ( needPathSegment ){ |
| builder.append(idType); |
| builder.append( " key=getPrimaryKey(id);\n"); // NOI18N |
| paramArg = "key"; // NOI18N |
| } |
| builder.append("return entityManager.find("); // NOI18N |
| builder.append(entitySimpleName); |
| builder.append(".class, "); // NOI18N |
| builder.append(paramArg); |
| builder.append(");"); // NOI18N |
| options.setBody(builder.toString()); |
| return options; |
| case FIND_ALL: |
| options.setBody("return find(true , -1 , -1);"); // NOI18N |
| return options; |
| case FIND_RANGE: |
| options.setBody("return find( false , max, first)"); // NOI18N |
| return options; |
| case COUNT: |
| builder = new StringBuilder("try {"); // NOI18N |
| builder.append("Query query = entityManager.createQuery("); // NOI18N |
| builder.append('"'); |
| builder.append("SELECT count(o) FROM "); // NOI18N |
| builder.append(getModel().getEntityInfo( entityFQN).getName()); |
| builder.append(" AS o\");"); // NOI18N |
| builder.append("return query.getSingleResult().toString();"); // NOI18N |
| builder.append("} finally { entityManager.close(); }"); // NOI18N |
| options.setBody( builder.toString()); |
| return options; |
| } |
| return null; |
| } |
| |
| private static final class FindMethod implements RestMethod { |
| |
| @Override |
| public boolean overrides() { |
| return false; |
| } |
| |
| @Override |
| public String getUriPath() { |
| return null; |
| } |
| |
| @Override |
| public String getMethodName() { |
| return "find"; // NOI18N |
| } |
| |
| @Override |
| public String getMethod() { |
| return null; |
| } |
| } |
| |
| private boolean hasAopAlliance; |
| } |