Line 0
Link Here
|
|
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 2012 Oracle and/or its affiliates. All rights reserved. |
5 |
* |
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
7 |
* Other names may be trademarks of their respective owners. |
8 |
* |
9 |
* The contents of this file are subject to the terms of either the GNU |
10 |
* General Public License Version 2 only ("GPL") or the Common |
11 |
* Development and Distribution License("CDDL") (collectively, the |
12 |
* "License"). You may not use this file except in compliance with the |
13 |
* License. You can obtain a copy of the License at |
14 |
* http://www.netbeans.org/cddl-gplv2.html |
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
16 |
* specific language governing permissions and limitations under the |
17 |
* License. When distributing the software, include this License Header |
18 |
* Notice in each file and include the License file at |
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this |
20 |
* particular file as subject to the "Classpath" exception as provided |
21 |
* by Oracle in the GPL Version 2 section of the License file that |
22 |
* accompanied this code. If applicable, add the following below the |
23 |
* License Header, with the fields enclosed by brackets [] replaced by |
24 |
* your own identifying information: |
25 |
* "Portions Copyrighted [year] [name of copyright owner]" |
26 |
* |
27 |
* If you wish your version of this file to be governed by only the CDDL |
28 |
* or only the GPL Version 2, indicate your decision by adding |
29 |
* "[Contributor] elects to include this software in this distribution |
30 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
31 |
* single choice of license, a recipient has the option to distribute |
32 |
* your version of this file under either the CDDL, the GPL Version 2 or |
33 |
* to extend the choice of license to its licensees as provided above. |
34 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
35 |
* Version 2 license, then the option applies only if the new code is |
36 |
* made subject to such option by the copyright holder. |
37 |
* |
38 |
* Contributor(s): |
39 |
* |
40 |
* Portions Copyrighted 2012 Sun Microsystems, Inc. |
41 |
*/ |
42 |
package org.netbeans.modules.refactoring.java.api; |
43 |
|
44 |
import org.netbeans.api.annotations.common.CheckForNull; |
45 |
import org.netbeans.api.annotations.common.NonNull; |
46 |
import org.netbeans.api.annotations.common.NullAllowed; |
47 |
import org.netbeans.api.java.source.TreePathHandle; |
48 |
import org.netbeans.modules.refactoring.api.AbstractRefactoring; |
49 |
import org.openide.filesystems.FileObject; |
50 |
import org.openide.util.lookup.Lookups; |
51 |
|
52 |
/** |
53 |
* Introduce Local Extension Refactoring. |
54 |
* |
55 |
* A server class you are using needs several additional methods, but you can’t |
56 |
* modify the class. |
57 |
* |
58 |
* Create a new class that contains these extra methods. Make this extension |
59 |
* class a subclass or a wrapper of the original. |
60 |
* |
61 |
* After running this refactoring use Move Refactoring to move the extra methods |
62 |
* to the newly created class. |
63 |
* |
64 |
* @author Ralph Ruijs |
65 |
* @since 1.33 |
66 |
*/ |
67 |
public final class IntroduceLocalExtensionRefactoring extends AbstractRefactoring { |
68 |
|
69 |
private String newName; |
70 |
private String packageName; |
71 |
private FileObject sourceRoot; |
72 |
private boolean wrap; |
73 |
private Equality equality; |
74 |
private boolean replace; |
75 |
|
76 |
/** |
77 |
* Create a new instance of IntroduceLocalExtensionRefactoring. |
78 |
* Equality will be {@code DELEGATE}. |
79 |
* |
80 |
* @param handle Path to the type to refactor. |
81 |
*/ |
82 |
public IntroduceLocalExtensionRefactoring(@NonNull TreePathHandle handle) { |
83 |
super(Lookups.singleton(handle)); |
84 |
this.equality = Equality.DELEGATE; |
85 |
this.wrap = false; |
86 |
this.replace = false; |
87 |
} |
88 |
|
89 |
/** |
90 |
* Getter for new name of the local extension. |
91 |
* |
92 |
* @return the new name |
93 |
*/ |
94 |
@CheckForNull |
95 |
public String getNewName() { |
96 |
return newName; |
97 |
} |
98 |
|
99 |
/** |
100 |
* Setter for new name of the local extension. |
101 |
* |
102 |
* @param newName new value for the new name |
103 |
*/ |
104 |
public void setNewName(@NullAllowed String newName) { |
105 |
this.newName = newName; |
106 |
} |
107 |
|
108 |
/** |
109 |
* Target for the local extension. |
110 |
* |
111 |
* The target for the local extension consists of the package name in |
112 |
* combination with the source root. |
113 |
* |
114 |
* @see #setSourceRoot |
115 |
* @param packageName |
116 |
*/ |
117 |
public void setPackageName(@NullAllowed String packageName) { |
118 |
this.packageName = packageName; |
119 |
} |
120 |
|
121 |
/** |
122 |
* Target for the local extension. |
123 |
* |
124 |
* @see #setPackageName |
125 |
* @return target |
126 |
*/ |
127 |
@CheckForNull |
128 |
public String getPackageName() { |
129 |
return packageName; |
130 |
} |
131 |
|
132 |
/** |
133 |
* Target for the local extension. |
134 |
* |
135 |
* The target for the local extension consists of the package name in |
136 |
* combination with the source root. |
137 |
* |
138 |
* @see #setPackageName |
139 |
* @param sourceRoot |
140 |
*/ |
141 |
public void setSourceRoot(FileObject sourceRoot) { |
142 |
this.sourceRoot = sourceRoot; |
143 |
} |
144 |
|
145 |
/** |
146 |
* Target for the local extension. |
147 |
* |
148 |
* @see #setSourceRoot |
149 |
* @return target |
150 |
*/ |
151 |
@CheckForNull |
152 |
public FileObject getSourceRoot() { |
153 |
return sourceRoot; |
154 |
} |
155 |
|
156 |
/** |
157 |
* The extension class can be a subclass or a wrapper of the original. |
158 |
* |
159 |
* When creating a wrapper class, a new class will be created with an |
160 |
* instance of the original. It will delegate all methods to the original. |
161 |
* |
162 |
* @param wrap true if the local extension should be a wrapper class. |
163 |
*/ |
164 |
public void setWrap(boolean wrap) { |
165 |
this.wrap = wrap; |
166 |
} |
167 |
|
168 |
/** |
169 |
* The extension class can be a subclass or a wrapper of the original. |
170 |
* |
171 |
* @return true if the local extension should be a wrapper class. |
172 |
*/ |
173 |
public boolean getWrap() { |
174 |
return wrap; |
175 |
} |
176 |
|
177 |
/** |
178 |
* Set how the equals and hashCode methods should be handled. |
179 |
* |
180 |
* Only makes sense if the extension is a wrapper class. |
181 |
* |
182 |
* @see Equality |
183 |
* @param equality how the equals and hashcode methods should be handled. |
184 |
*/ |
185 |
public void setEquality(@NonNull Equality equality) { |
186 |
this.equality = equality; |
187 |
} |
188 |
|
189 |
/** |
190 |
* Get how the equals and hashCode methods will be handled. |
191 |
* |
192 |
* Only makes sense if the extension is a wrapper class. |
193 |
* |
194 |
* @see Equality |
195 |
* @return how the equals and hashcode methods should be handled. |
196 |
*/ |
197 |
public @NonNull |
198 |
Equality getEquality() { |
199 |
return equality; |
200 |
} |
201 |
|
202 |
/** |
203 |
* Only create the extension class, or should all usages be replaced with |
204 |
* the new local extension. |
205 |
* |
206 |
* @param replace true if usages need to use the new type. |
207 |
*/ |
208 |
public void setReplace(boolean replace) { |
209 |
this.replace = replace; |
210 |
} |
211 |
|
212 |
/** |
213 |
* Only create the extension class, or should all usages be replaced with |
214 |
* the new local extension. |
215 |
* |
216 |
* @param replace true if usages need to use the new type. |
217 |
*/ |
218 |
public boolean getReplace() { |
219 |
return replace; |
220 |
} |
221 |
|
222 |
/** |
223 |
* Equality defines the different ways the equals and hashcode methods can |
224 |
* be handled. |
225 |
* |
226 |
* When creating a wrapper class the equals and hashcode methods should be |
227 |
* handled. Simply delegating it not always the best option, as the system |
228 |
* expects that equals is symmetric. |
229 |
*/ |
230 |
public enum Equality { |
231 |
|
232 |
/** |
233 |
* Delegate to the equals and hashcode methods to the original class. |
234 |
* |
235 |
* {@code |
236 |
* boolean equals(Object o) { |
237 |
* Object target = o; |
238 |
* if(o instanceof THIS) { |
239 |
* target = ((THIS)o).delegate; |
240 |
* } |
241 |
* return this.delegate.equals(target); |
242 |
* } |
243 |
* |
244 |
* int hashCode() { |
245 |
* return this.delegate.hashCode(); |
246 |
* } |
247 |
* } |
248 |
*/ |
249 |
DELEGATE, |
250 |
/** |
251 |
* Generate new hashcode and equals methods using the editors |
252 |
* codegenerator. |
253 |
* |
254 |
* The field {@code delegate} will be supplied to the equals and |
255 |
* hashcode generator. |
256 |
*/ |
257 |
GENERATE, |
258 |
/** |
259 |
* Separate the equals method into two. |
260 |
* A new method is added to check if the original class equals the |
261 |
* extension class. |
262 |
* {@code |
263 |
* boolean equals(Object o) { |
264 |
* return this.delegate.equals(o); |
265 |
* } |
266 |
* |
267 |
* boolean equalsSOURCE(THIS o) { |
268 |
* return this.delegate.equals(o.delegate); |
269 |
* } |
270 |
* |
271 |
* int hashCode() { |
272 |
* return this.delegate.hashCode(); |
273 |
* } |
274 |
* } |
275 |
*/ |
276 |
SEPARATE |
277 |
} |
278 |
} |