001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.j2ee.jpa.refactoring.rename;
043:
044: import java.text.MessageFormat;
045: import java.util.ArrayList;
046: import java.util.List;
047: import org.netbeans.api.fileinfo.NonRecursiveFolder;
048: import org.netbeans.api.java.classpath.ClassPath;
049: import org.netbeans.modules.j2ee.core.api.support.java.JavaIdentifiers;
050: import org.netbeans.modules.j2ee.persistence.dd.persistence.model_1_0.PersistenceUnit;
051: import org.netbeans.modules.j2ee.persistence.provider.ProviderUtil;
052: import org.netbeans.modules.j2ee.persistence.unit.PUDataObject;
053: import org.netbeans.modules.refactoring.api.AbstractRefactoring;
054: import org.netbeans.modules.refactoring.api.Problem;
055: import org.netbeans.modules.refactoring.api.RenameRefactoring;
056: import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
057: import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
058: import org.openide.filesystems.FileObject;
059: import org.openide.util.NbBundle;
060: import org.netbeans.modules.j2ee.jpa.refactoring.PersistenceXmlRefactoring;
061: import org.netbeans.modules.j2ee.jpa.refactoring.RefactoringUtil;
062: import org.netbeans.modules.j2ee.persistence.provider.InvalidPersistenceXmlException;
063: import org.openide.filesystems.FileUtil;
064:
065: /**
066: * Handles renaming of entity classes declared
067: * in a persistence.xml file when their package is renamed.
068: *
069: * @author Erno Mononen
070: */
071: public class PersistenceXmlPackageRename extends
072: PersistenceXmlRefactoring {
073:
074: private final RenameRefactoring renameRefactoring;
075:
076: public PersistenceXmlPackageRename(
077: RenameRefactoring renameRefactoring) {
078: this .renameRefactoring = renameRefactoring;
079: }
080:
081: protected AbstractRefactoring getRefactoring() {
082: return renameRefactoring;
083: }
084:
085: @Override
086: protected boolean shouldHandle() {
087: return true;
088: }
089:
090: @Override
091: public Problem prepare(RefactoringElementsBag refactoringElementsBag) {
092: if (isPackage()) {
093: FileObject pkg = renameRefactoring.getRefactoringSource()
094: .lookup(NonRecursiveFolder.class).getFolder();
095: String oldPackageName = JavaIdentifiers
096: .getQualifiedName(pkg);
097:
098: return doPrepare(refactoringElementsBag, pkg,
099: oldPackageName, renameRefactoring.getNewName());
100: } else if (isFolder()) {
101: FileObject folder = renameRefactoring
102: .getRefactoringSource().lookup(FileObject.class);
103: ClassPath classPath = ClassPath.getClassPath(folder,
104: ClassPath.SOURCE);
105: FileObject root = classPath.findOwnerRoot(folder);
106:
107: String prefix = FileUtil.getRelativePath(root,
108: folder.getParent()).replace('/', '.');
109: String oldName = buildName(prefix, folder.getName());
110: // the new package name
111: String newName = buildName(prefix, renameRefactoring
112: .getNewName());
113:
114: return doPrepare(refactoringElementsBag, folder, oldName,
115: newName);
116: }
117: return null;
118: }
119:
120: private boolean isPackage() {
121: return renameRefactoring.getRefactoringSource().lookup(
122: NonRecursiveFolder.class) != null;
123: }
124:
125: private boolean isFolder() {
126: FileObject folder = renameRefactoring.getRefactoringSource()
127: .lookup(FileObject.class);
128: return folder != null && folder.isFolder();
129: }
130:
131: /**
132: * Prepares the rename.
133: *
134: * @param refactoringElementsBag
135: * @param folder the folder or package to be renamed.
136: * @param oldName the old FQN of the folder / package.
137: * @param newName the new FQN of the folder / package.
138: */
139: private Problem doPrepare(
140: RefactoringElementsBag refactoringElementsBag,
141: FileObject folder, String oldName, String newName) {
142: Problem result = null;
143:
144: for (FileObject each : getPersistenceXmls(folder)) {
145: try {
146: PUDataObject pUDataObject = ProviderUtil
147: .getPUDataObject(each);
148: for (String clazz : getClasses(folder,
149: new ArrayList<String>())) {
150: List<PersistenceUnit> punits = getAffectedPersistenceUnits(
151: pUDataObject, clazz);
152: String newClassName = clazz.replace(oldName,
153: newName);
154: for (PersistenceUnit persistenceUnit : punits) {
155: refactoringElementsBag
156: .add(
157: getRefactoring(),
158: new PersistenceXmlPackageRenameRefactoringElement(
159: persistenceUnit, clazz,
160: newClassName,
161: pUDataObject, each));
162: }
163: }
164: } catch (InvalidPersistenceXmlException ex) {
165: Problem newProblem = new Problem(false, NbBundle
166: .getMessage(PersistenceXmlRefactoring.class,
167: "TXT_PersistenceXmlInvalidProblem", ex
168: .getPath()));
169:
170: result = RefactoringUtil.addToEnd(newProblem, result);
171: }
172: }
173: return result;
174:
175: }
176:
177: private String buildName(String prefix, String name) {
178: if (prefix.length() == 0) {
179: return name;
180: }
181: return prefix + "." + name;
182: }
183:
184: /**
185: * Collects the names of the classes from the given folder, recursively if possible (i.e. the given
186: * folder is not a NonRecursiveFolder).
187: *
188: * @return a list of fully qualified names of the classes in the given folder and its subfolders.
189: */
190: private List<String> getClasses(FileObject folder,
191: List<String> result) {
192: for (FileObject each : folder.getChildren()) {
193: if (each.isFolder()) {
194: getClasses(each, result);
195: } else {
196: result.add(JavaIdentifiers.getQualifiedName(each));
197: }
198: }
199: return result;
200: }
201:
202: protected RefactoringElementImplementation getRefactoringElement(
203: PersistenceUnit persistenceUnit, FileObject clazz,
204: PUDataObject pUDataObject, FileObject persistenceXml) {
205:
206: return null;
207: }
208:
209: /**
210: * A rename element for persistence.xml
211: */
212: private static class PersistenceXmlPackageRenameRefactoringElement
213: extends PersistenceXmlRefactoringElement {
214:
215: private final String newName;
216:
217: public PersistenceXmlPackageRenameRefactoringElement(
218: PersistenceUnit persistenceUnit, String oldName,
219: String newName, PUDataObject puDataObject,
220: FileObject parentFile) {
221: super (persistenceUnit, oldName, puDataObject, parentFile);
222: this .newName = newName;
223: }
224:
225: /**
226: * Returns text describing the refactoring formatted for display (using HTML tags).
227: * @return Formatted text.
228: */
229: public String getDisplayText() {
230: Object[] args = new Object[] { parentFile.getNameExt(),
231: clazz, newName };
232: return MessageFormat.format(NbBundle.getMessage(
233: PersistenceXmlRename.class,
234: "TXT_PersistenceXmlRename"), args);
235: }
236:
237: public void undoChange() {
238: ProviderUtil.renameManagedClass(persistenceUnit, clazz,
239: newName, puDataObject);
240: }
241:
242: /** Performs the change represented by this refactoring element.
243: */
244: public void performChange() {
245: ProviderUtil.renameManagedClass(persistenceUnit, newName,
246: clazz, puDataObject);
247: }
248:
249: }
250:
251: }
|