Skip to content

Commit 08fa722

Browse files
committed
Detect when components are renamed and rename their corresponding
generated descriptor files. Issues: 16, 17.
1 parent c1e9e05 commit 08fa722

17 files changed

Lines changed: 1004 additions & 144 deletions

ca.ecliptical.pde.ds-feature/feature.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<feature
1313
id="ca.ecliptical.pde.ds"
1414
label="%featureName"
15-
version="1.2.6.qualifier"
15+
version="1.2.7.qualifier"
1616
provider-name="%providerName"
1717
license-feature="ca.ecliptical.license"
1818
license-feature-version="1.0.0.qualifier">

ca.ecliptical.pde.ds/.project

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@
2020
<arguments>
2121
</arguments>
2222
</buildCommand>
23+
<buildCommand>
24+
<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
25+
<arguments>
26+
</arguments>
27+
</buildCommand>
2328
</buildSpec>
2429
<natures>
2530
<nature>org.eclipse.pde.PluginNature</nature>
2631
<nature>org.eclipse.jdt.core.javanature</nature>
32+
<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
2733
</natures>
2834
</projectDescription>

ca.ecliptical.pde.ds/META-INF/MANIFEST.MF

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %Bundle-Name
44
Bundle-SymbolicName: ca.ecliptical.pde.ds;singleton:=true
5-
Bundle-Version: 1.2.6.qualifier
5+
Bundle-Version: 1.2.7.qualifier
66
Bundle-Activator: ca.ecliptical.pde.internal.ds.Activator
77
Bundle-Vendor: %Bundle-Vendor
88
Require-Bundle: org.eclipse.ui;bundle-version="[3.105.0,4.0.0)",
@@ -11,7 +11,10 @@ Require-Bundle: org.eclipse.ui;bundle-version="[3.105.0,4.0.0)",
1111
org.eclipse.jdt.core;bundle-version="[3.9.0,4.0.0)",
1212
org.eclipse.pde.ds.core;bundle-version="[1.0.300,1.1.0)",
1313
org.eclipse.core.resources;bundle-version="[3.8.100,4.0.0)",
14-
org.eclipse.jface.text;bundle-version="[3.8.100,4.0.0)"
14+
org.eclipse.jface.text;bundle-version="[3.8.100,4.0.0)",
15+
org.eclipse.ltk.core.refactoring;bundle-version="[3.6.100,4.0.0)",
16+
org.eclipse.core.expressions;bundle-version="[3.4.501,4.0.0)",
17+
org.eclipse.core.filebuffers;bundle-version="[3.5.300,4.0.0)"
1518
Bundle-RequiredExecutionEnvironment: J2SE-1.5
1619
Bundle-ActivationPolicy: lazy
1720
Export-Package: ca.ecliptical.pde.internal.ds;x-internal:=true

ca.ecliptical.pde.ds/OSGI-INF/l10n/bundle.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ keyword.label = ds
1414
property.page.name = DS Annotations
1515
preference.page.name = DS Annotations
1616
problem.marker.name = DS Annotation Problem
17-
content-type-v12.name = Service Component File v1.2
17+
content-type-v12.name = Service Component File v1.2
18+
renameParticipant.name = Rename DS component implementation class
19+
moveParticipant.name = Move DS component implementation class

ca.ecliptical.pde.ds/plugin.xml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,86 @@
7777
</describer>
7878
</content-type>
7979
</extension>
80+
<extension
81+
point="org.eclipse.ltk.core.refactoring.renameParticipants">
82+
<renameParticipant
83+
class="ca.ecliptical.pde.internal.ds.ComponentRenameParticipant"
84+
id="ca.ecliptical.pde.ds.ComponentRenameParticipant"
85+
name="%renameParticipant.name">
86+
<enablement>
87+
<with variable="affectedNatures">
88+
<iterate
89+
ifEmpty="false"
90+
operator="or">
91+
<equals
92+
value="org.eclipse.jdt.core.javanature">
93+
</equals>
94+
</iterate>
95+
<iterate
96+
ifEmpty="false"
97+
operator="or">
98+
<equals
99+
value="org.eclipse.pde.PluginNature">
100+
</equals>
101+
</iterate>
102+
</with>
103+
<with variable="element">
104+
<or>
105+
<instanceof
106+
value="org.eclipse.jdt.core.IType">
107+
</instanceof>
108+
<instanceof
109+
value="org.eclipse.jdt.core.IPackageFragment">
110+
</instanceof>
111+
</or>
112+
<test property="org.eclipse.jdt.core.hasTypeOnClasspath" value="org.osgi.service.component.annotations.Component"/>
113+
<test property="ca.ecliptical.pde.ds.containsComponentWithImplicitName" value="true"/>
114+
</with>
115+
</enablement>
116+
</renameParticipant>
117+
</extension>
118+
<extension
119+
point="org.eclipse.ltk.core.refactoring.moveParticipants">
120+
<moveParticipant
121+
class="ca.ecliptical.pde.internal.ds.ComponentMoveParticipant"
122+
id="ca.ecliptical.pde.ds.ComponentMoveParticipant"
123+
name="%moveParticipant.name">
124+
<enablement>
125+
<with variable="affectedNatures">
126+
<iterate
127+
ifEmpty="false"
128+
operator="or">
129+
<equals
130+
value="org.eclipse.jdt.core.javanature">
131+
</equals>
132+
</iterate>
133+
<iterate
134+
ifEmpty="false"
135+
operator="or">
136+
<equals
137+
value="org.eclipse.pde.PluginNature">
138+
</equals>
139+
</iterate>
140+
</with>
141+
<with variable="element">
142+
<instanceof
143+
value="org.eclipse.jdt.core.IType">
144+
</instanceof>
145+
<test property="org.eclipse.jdt.core.hasTypeOnClasspath" value="org.osgi.service.component.annotations.Component"/>
146+
<test property="ca.ecliptical.pde.ds.containsComponentWithImplicitName" value="true"/>
147+
</with>
148+
</enablement>
149+
</moveParticipant>
150+
</extension>
151+
<extension
152+
point="org.eclipse.core.expressions.propertyTesters">
153+
<propertyTester
154+
class="ca.ecliptical.pde.internal.ds.ComponentPropertyTester"
155+
id="ca.ecliptical.pde.ds.ComponentPropertyTester"
156+
namespace="ca.ecliptical.pde.ds"
157+
properties="containsComponentWithImplicitName"
158+
type="org.eclipse.jdt.core.IParent">
159+
</propertyTester>
160+
</extension>
80161

81162
</plugin>

ca.ecliptical.pde.ds/src/ca/ecliptical/pde/internal/ds/AnnotationProcessor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ private IDSModel processComponent(TypeDeclaration type, ITypeBinding typeBinding
489489
}
490490

491491
if (!errorLevel.isNone()) {
492-
String expected = property.getPropertyType() == null || property.getPropertyType().isEmpty() || String.class.getSimpleName().equals(property.getPropertyType()) ? Messages.AnnotationProcessor_stringOrEmpty : property.getPropertyType();
492+
String expected = property.getPropertyType() == null || property.getPropertyType().length() == 0 || String.class.getSimpleName().equals(property.getPropertyType()) ? Messages.AnnotationProcessor_stringOrEmpty : property.getPropertyType();
493493
String actual = propertyType == null || String.class.getSimpleName().equals(propertyType) ? Messages.AnnotationProcessor_stringOrEmpty : propertyType;
494494
if (!actual.equals(expected))
495495
reportProblem(annotation, "property", i, problems, NLS.bind(Messages.AnnotationProcessor_inconsistentComponentPropertyType, actual, expected), actual); //$NON-NLS-1$
@@ -650,7 +650,7 @@ private void validateComponentProperty(Annotation annotation, String name, Strin
650650
return;
651651

652652
if (PROPERTY_TYPES.contains(type)) {
653-
if (name == null || name.trim().isEmpty())
653+
if (name == null || name.trim().length() == 0)
654654
reportProblem(annotation, "property", index, problems, Messages.AnnotationProcessor_invalidComponentProperty_nameRequired, name); //$NON-NLS-1$
655655

656656
if (value == null) {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2015 Ecliptical Software Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Ecliptical Software Inc. - initial API and implementation
10+
*******************************************************************************/
11+
package ca.ecliptical.pde.internal.ds;
12+
13+
import org.eclipse.core.runtime.CoreException;
14+
import org.eclipse.core.runtime.IProgressMonitor;
15+
import org.eclipse.core.runtime.OperationCanceledException;
16+
import org.eclipse.jdt.core.IJavaElement;
17+
import org.eclipse.jdt.core.IPackageFragment;
18+
import org.eclipse.jdt.core.IType;
19+
import org.eclipse.ltk.core.refactoring.Change;
20+
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
21+
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
22+
import org.eclipse.ltk.core.refactoring.participants.ISharableParticipant;
23+
import org.eclipse.ltk.core.refactoring.participants.MoveArguments;
24+
import org.eclipse.ltk.core.refactoring.participants.MoveParticipant;
25+
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
26+
27+
public class ComponentMoveParticipant extends MoveParticipant implements ISharableParticipant, ComponentRefactoringParticipant {
28+
29+
private final ComponentRefactoringHelper helper = new ComponentRefactoringHelper(this);
30+
31+
@Override
32+
protected boolean initialize(Object element) {
33+
return helper.initialize(element);
34+
}
35+
36+
@Override
37+
public String getName() {
38+
return Messages.ComponentMoveParticipant_name;
39+
}
40+
41+
public void addElement(Object element, RefactoringArguments arguments) {
42+
helper.addElement(element, arguments);
43+
}
44+
45+
@Override
46+
public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) throws OperationCanceledException {
47+
return helper.checkConditions(pm, context);
48+
}
49+
50+
@Override
51+
public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
52+
return helper.createChange(pm);
53+
}
54+
55+
public String getComponentNameRoot(IJavaElement element, RefactoringArguments args) {
56+
IType type = (IType) element;
57+
String compName = type.getFullyQualifiedName();
58+
Object destination = ((MoveArguments) args).getDestination();
59+
if (destination instanceof IPackageFragment) {
60+
compName = String.format("%s.%s", ((IPackageFragment) destination).getElementName(), type.getElementName()); //$NON-NLS-1$
61+
} else if (destination instanceof IType) {
62+
compName = ((IType) destination).getType(type.getElementName()).getFullyQualifiedName();
63+
}
64+
65+
return compName;
66+
}
67+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2015 Ecliptical Software Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Ecliptical Software Inc. - initial API and implementation
10+
*******************************************************************************/
11+
package ca.ecliptical.pde.internal.ds;
12+
13+
import org.eclipse.core.expressions.PropertyTester;
14+
import org.eclipse.core.resources.ProjectScope;
15+
import org.eclipse.core.runtime.Platform;
16+
import org.eclipse.core.runtime.preferences.IScopeContext;
17+
import org.eclipse.core.runtime.preferences.InstanceScope;
18+
import org.eclipse.jdt.core.IAnnotation;
19+
import org.eclipse.jdt.core.ICompilationUnit;
20+
import org.eclipse.jdt.core.IJavaElement;
21+
import org.eclipse.jdt.core.IJavaProject;
22+
import org.eclipse.jdt.core.IMemberValuePair;
23+
import org.eclipse.jdt.core.IPackageFragment;
24+
import org.eclipse.jdt.core.IType;
25+
import org.eclipse.jdt.core.JavaModelException;
26+
import org.eclipse.pde.internal.ds.core.IDSConstants;
27+
import org.osgi.service.component.annotations.Component;
28+
29+
/**
30+
* Tests if a type (or any nested type) has a {@link Component} annotation with
31+
* no <code>name</code> attribute.
32+
*/
33+
@SuppressWarnings("restriction")
34+
public class ComponentPropertyTester extends PropertyTester {
35+
36+
private static final String COMPONENT_ANNOTATION = DSAnnotationCompilationParticipant.COMPONENT_ANNOTATION;
37+
38+
private static final String COMPONENT_PACKAGE = COMPONENT_ANNOTATION.substring(0, COMPONENT_ANNOTATION.lastIndexOf('.'));
39+
40+
private static final String COMPONENT_NAME = Component.class.getSimpleName();
41+
42+
private static final Debug debug = Debug.getDebug("component-property-tester"); //$NON-NLS-1$
43+
44+
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
45+
if (!"containsComponentWithImplicitName".equals(property)) //$NON-NLS-1$
46+
return false;
47+
48+
if (!(receiver instanceof IType) && !(receiver instanceof IPackageFragment))
49+
return false;
50+
51+
IJavaElement element = (IJavaElement) receiver;
52+
IJavaProject javaProject = element.getJavaProject();
53+
54+
boolean enabled = Platform.getPreferencesService().getBoolean(Activator.PLUGIN_ID, Activator.PREF_ENABLED, true, new IScopeContext[] { new ProjectScope(javaProject.getProject()), InstanceScope.INSTANCE });
55+
if (!enabled)
56+
return false;
57+
58+
try {
59+
return element.getElementType() == IJavaElement.TYPE ? containsImplicitName((IType) receiver) : containsImplicitName((IPackageFragment) receiver);
60+
} catch (JavaModelException e) {
61+
if (debug.isDebugging())
62+
debug.trace(String.format("Error searching for components with implicit names in element: %s", element), e); //$NON-NLS-1$
63+
}
64+
65+
return false;
66+
}
67+
68+
private boolean containsImplicitName(IPackageFragment fragment) throws JavaModelException {
69+
if (!fragment.containsJavaResources())
70+
return false;
71+
72+
for (ICompilationUnit cu : fragment.getCompilationUnits()) {
73+
for (IType type : cu.getAllTypes()) {
74+
if (hasImplicitName(type))
75+
return true;
76+
}
77+
}
78+
79+
return false;
80+
}
81+
82+
private boolean containsImplicitName(IType type) throws JavaModelException {
83+
if (hasImplicitName(type))
84+
return true;
85+
86+
for (IType child : type.getTypes()) {
87+
if (hasImplicitName(child))
88+
return true;
89+
}
90+
91+
return false;
92+
}
93+
94+
public static boolean hasImplicitName(IType type) throws JavaModelException {
95+
IAnnotation[] annotations = type.getAnnotations();
96+
for (IAnnotation annotation : annotations) {
97+
boolean isComponent = COMPONENT_ANNOTATION.equals(annotation.getElementName());
98+
if (!isComponent) {
99+
String[][] resolved = type.resolveType(annotation.getElementName());
100+
if (resolved != null) {
101+
for (String[] pair : resolved) {
102+
if (pair.length == 2
103+
&& COMPONENT_PACKAGE.equals(pair[0])
104+
&& COMPONENT_NAME.equals(pair[1])) {
105+
isComponent = true;
106+
break;
107+
}
108+
}
109+
}
110+
}
111+
112+
if (isComponent) {
113+
IMemberValuePair[] attrs = annotation.getMemberValuePairs();
114+
for (IMemberValuePair attr : attrs) {
115+
if (IDSConstants.ATTRIBUTE_COMPONENT_NAME.equals(attr.getMemberName())) {
116+
return false;
117+
}
118+
}
119+
120+
return true;
121+
}
122+
}
123+
124+
return false;
125+
}
126+
}

0 commit comments

Comments
 (0)