1 11 package org.eclipse.pde.internal.ui.refactoring; 12 13 import org.eclipse.core.filebuffers.FileBuffers; 14 import org.eclipse.core.filebuffers.ITextFileBuffer; 15 import org.eclipse.core.filebuffers.ITextFileBufferManager; 16 import org.eclipse.core.resources.IContainer; 17 import org.eclipse.core.resources.IFile; 18 import org.eclipse.core.resources.IResource; 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.IProgressMonitor; 21 import org.eclipse.core.runtime.Path; 22 import org.eclipse.jdt.core.IJavaElement; 23 import org.eclipse.jdt.core.IPackageFragment; 24 import org.eclipse.jdt.core.IType; 25 import org.eclipse.jface.text.IDocument; 26 import org.eclipse.ltk.core.refactoring.Change; 27 import org.eclipse.ltk.core.refactoring.TextChange; 28 import org.eclipse.ltk.core.refactoring.TextFileChange; 29 import org.eclipse.pde.core.plugin.IPluginAttribute; 30 import org.eclipse.pde.core.plugin.IPluginElement; 31 import org.eclipse.pde.core.plugin.IPluginExtension; 32 import org.eclipse.pde.core.plugin.IPluginObject; 33 import org.eclipse.pde.core.plugin.IPluginParent; 34 import org.eclipse.pde.internal.core.PDECore; 35 import org.eclipse.pde.internal.core.ischema.IMetaAttribute; 36 import org.eclipse.pde.internal.core.ischema.ISchema; 37 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute; 38 import org.eclipse.pde.internal.core.ischema.ISchemaElement; 39 import org.eclipse.pde.internal.core.schema.SchemaRegistry; 40 import org.eclipse.pde.internal.core.text.IDocumentAttribute; 41 import org.eclipse.pde.internal.core.text.plugin.FragmentModel; 42 import org.eclipse.pde.internal.core.text.plugin.PluginModel; 43 import org.eclipse.pde.internal.core.text.plugin.PluginModelBase; 44 import org.eclipse.pde.internal.core.text.plugin.PluginNode; 45 import org.eclipse.text.edits.MultiTextEdit; 46 import org.eclipse.text.edits.ReplaceEdit; 47 import org.eclipse.text.edits.TextEdit; 48 49 public class PluginManifestChange { 50 51 public static Change createRenameChange(IFile file, Object [] affectedElements, String [] newNames, TextChange textChange, IProgressMonitor monitor) 52 throws CoreException { 53 ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager(); 54 try { 55 manager.connect(file.getFullPath(), monitor); 56 ITextFileBuffer buffer = manager.getTextFileBuffer(file.getFullPath()); 57 58 MultiTextEdit multiEdit = new MultiTextEdit(); 59 60 IDocument document = buffer.getDocument(); 61 62 try { 63 PluginModelBase model; 64 if ("fragment.xml".equals(file.getName())) model = new FragmentModel(document, false); 66 else 67 model = new PluginModel(document, false); 68 69 model.load(); 70 if (!model.isLoaded()) 71 return null; 72 73 for (int i = 0; i < affectedElements.length; i++) { 74 if (model instanceof PluginModel && affectedElements[i] instanceof IJavaElement) { 75 PluginNode plugin = (PluginNode)model.getPluginBase(); 76 IDocumentAttribute attr = plugin.getDocumentAttribute("class"); TextEdit edit = createTextEdit(attr, (IJavaElement)affectedElements[i], newNames[i]); 78 if (edit != null) 79 multiEdit.addChild(edit); 80 } 81 82 SchemaRegistry registry = PDECore.getDefault().getSchemaRegistry(); 83 IPluginExtension[] extensions = model.getPluginBase().getExtensions(); 84 for (int j = 0; j < extensions.length; j++) { 85 ISchema schema = registry.getSchema(extensions[j].getPoint()); 86 if (schema != null) 87 addExtensionAttributeEdit(schema, extensions[j], multiEdit, affectedElements[i], newNames[i]); 88 } 89 } 90 91 if (multiEdit.hasChildren()) { 92 if (textChange != null) { 94 TextEdit edit = textChange.getEdit(); 95 if (edit instanceof MultiTextEdit) { 96 ((MultiTextEdit)edit).addChild(multiEdit); 97 multiEdit = ((MultiTextEdit)edit); 98 } 99 else 100 multiEdit.addChild(edit); 101 } 102 TextFileChange change = new TextFileChange("", file); change.setEdit(multiEdit); 104 return change; 105 } 106 } catch (CoreException e) { 107 return null; 108 } 109 return null; 110 } finally { 111 manager.disconnect(file.getFullPath(), monitor); 112 } 113 } 114 115 private static void addExtensionAttributeEdit(ISchema schema, IPluginParent parent, MultiTextEdit multi, Object element, String newName) { 116 IPluginObject[] children = parent.getChildren(); 117 for (int i = 0; i < children.length; i++) { 118 IPluginElement child = (IPluginElement)children[i]; 119 ISchemaElement schemaElement = schema.findElement(child.getName()); 120 if (schemaElement != null) { 121 IPluginAttribute[] attributes = child.getAttributes(); 122 for (int j = 0; j < attributes.length; j++) { 123 IPluginAttribute attr = attributes[j]; 124 ISchemaAttribute attInfo = schemaElement.getAttribute(attr.getName()); 125 if (attInfo != null) { 126 if (element instanceof IJavaElement && attInfo.getKind() == IMetaAttribute.JAVA) { 127 IDocumentAttribute docAttr = (IDocumentAttribute)attr; 128 TextEdit edit = createTextEdit(docAttr, (IJavaElement)element, newName); 129 if (edit != null) 130 multi.addChild(edit); 131 } else if (element instanceof IResource && attInfo.getKind() == IMetaAttribute.RESOURCE) { 132 IDocumentAttribute docAttr = (IDocumentAttribute)attr; 133 TextEdit edit = createTextEdit(docAttr, (IResource)element, newName); 134 if (edit != null) 135 multi.addChild(edit); 136 } 137 } 138 } 139 } 140 addExtensionAttributeEdit(schema, child, multi, element, newName); 141 } 142 } 143 144 private static TextEdit createTextEdit(IDocumentAttribute attr, IJavaElement element, String newName) { 145 if (attr == null) 146 return null; 147 148 String oldName = (element instanceof IType) 149 ? ((IType)element).getFullyQualifiedName('$') 150 : element.getElementName(); 151 String value = attr.getAttributeValue(); 152 if (oldName.equals(value) || isGoodMatch(value, oldName, element instanceof IPackageFragment)) { 153 int offset = attr.getValueOffset(); 154 if (offset >= 0) 155 return new ReplaceEdit(offset, oldName.length(), newName); 156 } 157 return null; 158 } 159 160 private static TextEdit createTextEdit(IDocumentAttribute attr, IResource resource, String newName) { 161 if (attr != null) { 162 String oldName = resource.getProjectRelativePath().toString(); 163 String value = attr.getAttributeValue(); 164 if (oldName.equals(value) || ((resource instanceof IContainer) && isGoodFolderMatch(value, oldName))) { 165 int offset = attr.getValueOffset(); 166 if (offset >= 0) 167 return new ReplaceEdit(offset, oldName.length(), newName); 168 } 169 } 170 return null; 171 } 172 173 private static boolean isGoodMatch(String value, String oldName, boolean isPackage) { 174 if (value == null || value.length() <= oldName.length()) 175 return false; 176 boolean goodLengthMatch = isPackage 177 ? value.lastIndexOf('.') <= oldName.length() 178 : value.charAt(oldName.length()) == '$'; 179 return value.startsWith(oldName) && goodLengthMatch; 180 } 181 182 private static boolean isGoodFolderMatch(String value, String oldName) { 183 return new Path(oldName).isPrefixOf(new Path(value)); 184 } 185 } 186 | Popular Tags |