| /* |
| * 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.j2ee.jpa.refactoring.rename; |
| |
| import com.sun.source.tree.AnnotationTree; |
| import com.sun.source.tree.AssignmentTree; |
| import com.sun.source.tree.ExpressionTree; |
| import com.sun.source.tree.LiteralTree; |
| import java.io.IOException; |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| import javax.lang.model.element.AnnotationMirror; |
| import javax.lang.model.element.AnnotationValue; |
| import javax.lang.model.element.Element; |
| import javax.lang.model.element.ExecutableElement; |
| import javax.lang.model.element.TypeElement; |
| import org.netbeans.api.java.source.CancellableTask; |
| import org.netbeans.api.java.source.JavaSource; |
| import org.netbeans.api.java.source.TreeMaker; |
| import org.netbeans.api.java.source.TreePathHandle; |
| import org.netbeans.api.java.source.WorkingCopy; |
| import org.netbeans.api.project.FileOwnerQuery; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.modules.j2ee.jpa.refactoring.EntityAnnotationReference; |
| import org.netbeans.modules.j2ee.jpa.refactoring.EntityAssociationResolver; |
| import org.netbeans.modules.j2ee.jpa.refactoring.RefactoringUtil; |
| import org.netbeans.modules.j2ee.metadata.model.api.MetadataModel; |
| import org.netbeans.modules.j2ee.persistence.api.PersistenceScope; |
| import org.netbeans.modules.j2ee.persistence.api.PersistenceScopes; |
| import org.netbeans.modules.j2ee.persistence.api.metadata.orm.EntityMappingsMetadata; |
| import org.netbeans.modules.refactoring.api.Problem; |
| import org.netbeans.modules.refactoring.api.RenameRefactoring; |
| import org.netbeans.modules.refactoring.java.spi.JavaRefactoringPlugin; |
| import org.netbeans.modules.refactoring.spi.RefactoringElementsBag; |
| import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImplementation; |
| import org.openide.filesystems.FileObject; |
| import org.openide.text.PositionBounds; |
| import org.openide.util.Exceptions; |
| import org.openide.util.Lookup; |
| import org.openide.util.NbBundle; |
| import org.openide.util.lookup.Lookups; |
| |
| /** |
| * Handles renaming of properties that are referenced by |
| * the mappedBy attribute. |
| * |
| * @author Erno Mononen |
| */ |
| public class EntityRename extends JavaRefactoringPlugin { |
| |
| private final RenameRefactoring rename; |
| private TreePathHandle treePathHandle; |
| |
| public EntityRename(RenameRefactoring rename) { |
| this.rename = rename; |
| try { |
| this.treePathHandle = RefactoringUtil.resolveTreePathHandle(rename); |
| } catch (IOException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| } |
| |
| @Override |
| public Problem preCheck() { |
| return null; |
| } |
| |
| @Override |
| public Problem fastCheckParameters() { |
| return null; |
| } |
| |
| @Override |
| public Problem checkParameters() { |
| return null; |
| } |
| |
| @Override |
| protected JavaSource getJavaSource(Phase p) { |
| return null; |
| } |
| |
| private PersistenceScope getPersistenceScope() { |
| if (treePathHandle == null) { |
| return null; |
| } |
| Project project = FileOwnerQuery.getOwner(treePathHandle.getFileObject()); |
| if (project == null) { |
| return null; |
| } |
| |
| PersistenceScopes scopes = PersistenceScopes.getPersistenceScopes(project); |
| |
| if (scopes == null) { |
| return null; // project of this type doesn't provide a list of persistence scopes |
| } |
| |
| if (scopes.getPersistenceScopes().length == 0) { |
| return null; |
| } |
| |
| return scopes.getPersistenceScopes()[0]; |
| |
| } |
| |
| private MetadataModel<EntityMappingsMetadata> getEntityMappingsModel() { |
| PersistenceScope scope = getPersistenceScope(); |
| // XXX should retrieve the model for each PU (see the javadoc of the |
| // the scope#getEMM(String) method), but it is currently not supported |
| // by the persistence scope implementations. |
| return scope != null ? scope.getEntityMappingsModel(null) : null; |
| } |
| |
| @Override |
| public Problem prepare(RefactoringElementsBag refactoringElementsBag) { |
| |
| MetadataModel<EntityMappingsMetadata> emModel = getEntityMappingsModel(); |
| if (emModel == null) { |
| return null; |
| } |
| |
| EntityAssociationResolver resolver = new EntityAssociationResolver(treePathHandle, emModel); |
| try { |
| List<EntityAnnotationReference> references = resolver.resolveReferences(); |
| for (EntityAnnotationReference ref : references) { |
| EntityRenameElement element = new EntityRenameElement(ref, rename); |
| refactoringElementsBag.add(rename, element); |
| } |
| } catch (IOException ioe) { |
| Exceptions.printStackTrace(ioe); |
| } |
| return null; |
| } |
| |
| private static class EntityRenameElement extends SimpleRefactoringElementImplementation { |
| |
| private final RenameRefactoring rename; |
| private final EntityAnnotationReference reference; |
| |
| public EntityRenameElement(EntityAnnotationReference reference, RenameRefactoring rename) { |
| this.reference = reference; |
| this.rename = rename; |
| } |
| |
| @Override |
| public String getText() { |
| return getDisplayText(); |
| } |
| |
| @Override |
| public String getDisplayText() { |
| Object[] args = new Object[]{reference.getHandle().getFileObject().getNameExt(), reference.getAttributeValue(), rename.getNewName()}; |
| return MessageFormat.format(NbBundle.getMessage(EntityRename.class, "TXT_EntityAnnotationRename"), args); |
| } |
| |
| @Override |
| public void performChange() { |
| try { |
| JavaSource source = JavaSource.forFileObject(reference.getHandle().getFileObject()); |
| source.runModificationTask(new CancellableTask<WorkingCopy>() { |
| |
| @Override |
| public void cancel() { |
| } |
| |
| @Override |
| public void run(WorkingCopy workingCopy) throws Exception { |
| |
| workingCopy.toPhase(JavaSource.Phase.RESOLVED); |
| Element element = reference.getHandle().resolveElement(workingCopy); |
| |
| for (AnnotationMirror annotation : element.getAnnotationMirrors()) { |
| |
| if (!annotation.getAnnotationType().toString().equals(reference.getAnnotation())) { |
| continue; |
| } |
| |
| Map<? extends ExecutableElement, ? extends AnnotationValue> values = annotation.getElementValues(); |
| |
| TreeMaker make = workingCopy.getTreeMaker(); |
| AnnotationTree oldAt = (AnnotationTree) workingCopy.getTrees().getTree(element, annotation); |
| List<? extends ExpressionTree> arguments = oldAt.getArguments(); |
| ArrayList<ExpressionTree> newArguments = new ArrayList<ExpressionTree>(); |
| for (ExpressionTree argument : arguments) { |
| ExpressionTree tmp = argument; |
| if (argument instanceof AssignmentTree) { |
| AssignmentTree assignment = (AssignmentTree) argument; |
| ExpressionTree expression = assignment.getExpression(); |
| ExpressionTree variable = assignment.getVariable(); |
| if (expression instanceof LiteralTree) { |
| LiteralTree literal = (LiteralTree) expression; |
| String value = literal.getValue().toString(); |
| if (reference.getAttributeValue().equals(value)) { |
| tmp = make.Assignment(variable, make.Literal(rename.getNewName())); |
| } |
| } |
| } |
| newArguments.add(tmp); |
| } |
| TypeElement typeElement = workingCopy.getElements().getTypeElement(reference.getAnnotation()); |
| AnnotationTree newAt = make.Annotation(make.QualIdent(typeElement), newArguments); |
| |
| workingCopy.rewrite(oldAt, newAt); |
| } |
| |
| } |
| }).commit(); |
| |
| } catch (IOException ioe) { |
| Exceptions.printStackTrace(ioe); |
| } |
| } |
| |
| @Override |
| public Lookup getLookup() { |
| return Lookups.singleton(reference.getHandle().getFileObject()); |
| } |
| |
| @Override |
| public FileObject getParentFile() { |
| return reference.getHandle().getFileObject(); |
| } |
| |
| @Override |
| public PositionBounds getPosition() { |
| |
| return null; |
| } |
| } |
| } |