1 /*******************************************************************************
2  * Copyright (c) 2006, 2016 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.corext.refactoring;
15 
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.List;
19 
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IAdaptable;
23 
24 import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
25 
26 import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore;
27 import org.eclipse.jdt.internal.core.manipulation.JavaManipulationPlugin;
28 import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
29 import org.eclipse.jdt.internal.corext.refactoring.rename.RenamingNameSuggestor;
30 import org.eclipse.jdt.internal.corext.refactoring.reorg.IReorgPolicy;
31 import org.eclipse.jdt.internal.corext.refactoring.reorg.IReorgPolicy.IMovePolicy;
32 import org.eclipse.jdt.internal.corext.refactoring.tagging.IDelegateUpdating;
33 import org.eclipse.jdt.internal.corext.refactoring.tagging.INameUpdating;
34 import org.eclipse.jdt.internal.corext.refactoring.tagging.IQualifiedNameUpdating;
35 import org.eclipse.jdt.internal.corext.refactoring.tagging.IReferenceUpdating;
36 import org.eclipse.jdt.internal.corext.refactoring.tagging.ISimilarDeclarationUpdating;
37 import org.eclipse.jdt.internal.corext.refactoring.tagging.ITextUpdating;
38 import org.eclipse.jdt.internal.corext.util.Messages;
39 
40 /**
41  * Helper class to generate a refactoring descriptor comment.
42  *
43  * @since 3.2
44  */
45 public final class JDTRefactoringDescriptorComment {
46 
47 	/** The element delimiter */
48 	private static final String ELEMENT_DELIMITER= RefactoringCoreMessages.JavaRefactoringDescriptorComment_element_delimiter;
49 
50 	/** The line delimiter */
51 	private static final String LINE_DELIMITER= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
52 
53 	/**
54 	 * Creates a composite setting.
55 	 *
56 	 * @param caption
57 	 *            the caption
58 	 * @param settings
59 	 *            the settings
60 	 * @return the composite setting
61 	 */
createCompositeSetting(final String caption, final String[] settings)62 	public static String createCompositeSetting(final String caption, final String[] settings) {
63 		Assert.isNotNull(caption);
64 		Assert.isNotNull(settings);
65 		final StringBuilder buffer= new StringBuilder(128);
66 		for (String setting : settings) {
67 			if (setting != null && !"".equals(setting)) { //$NON-NLS-1$
68 				buffer.append(LINE_DELIMITER);
69 				buffer.append(ELEMENT_DELIMITER);
70 				buffer.append(setting);
71 			} else {
72 				buffer.append(LINE_DELIMITER);
73 				buffer.append(ELEMENT_DELIMITER);
74 				buffer.append(RefactoringCoreMessages.JavaRefactoringDescriptor_not_available);
75 			}
76 		}
77 		if (buffer.length() > 0)
78 			buffer.insert(0, caption);
79 		return buffer.toString();
80 	}
81 
82 	/** The header of the comment */
83 	private final String fHeader;
84 
85 	/** The project name, or <code>null</code> */
86 	private final String fProject;
87 
88 	/** The settings list */
89 	private final List<String> fSettings= new ArrayList<>(6);
90 
91 	/**
92 	 * Creates a new JDT refactoring descriptor comment.
93 	 *
94 	 * @param project
95 	 *            the project name, or <code>null</code>
96 	 * @param object
97 	 *            the refactoring object to generate a comment for
98 	 * @param header
99 	 *            the header of the comment (typically the unique description of
100 	 *            the refactoring with fully qualified element names)
101 	 */
JDTRefactoringDescriptorComment(final String project, final Object object, final String header)102 	public JDTRefactoringDescriptorComment(final String project, final Object object, final String header) {
103 		Assert.isNotNull(object);
104 		Assert.isNotNull(header);
105 		fProject= project;
106 		fHeader= header;
107 		initializeInferredSettings(object);
108 	}
109 
110 	/**
111 	 * Adds the specified setting to this comment.
112 	 *
113 	 * @param index
114 	 *            the index
115 	 * @param setting
116 	 *            the setting to add
117 	 */
addSetting(final int index, final String setting)118 	public void addSetting(final int index, final String setting) {
119 		Assert.isTrue(index >= 0);
120 		Assert.isNotNull(setting);
121 		Assert.isTrue(!"".equals(setting)); //$NON-NLS-1$
122 		fSettings.add(index, setting);
123 	}
124 
125 	/**
126 	 * Adds the specified setting to this comment.
127 	 *
128 	 * @param setting
129 	 *            the setting to add, or <code>null</code> for no setting
130 	 */
addSetting(final String setting)131 	public void addSetting(final String setting) {
132 		if (setting != null && !"".equals(setting)) //$NON-NLS-1$
133 			fSettings.add(setting);
134 	}
135 
136 	/**
137 	 * Returns this comment in a human-readable string representation.
138 	 *
139 	 * @return this comment in string representation
140 	 */
asString()141 	public String asString() {
142 		final StringBuilder buffer= new StringBuilder(256);
143 		buffer.append(fHeader);
144 		if (fProject != null && !"".equals(fProject)) { //$NON-NLS-1$
145 			buffer.append(LINE_DELIMITER);
146 			buffer.append(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptorComment_original_project, BasicElementLabels.getResourceName(fProject)));
147 		}
148 		for (String setting : fSettings) {
149 			buffer.append(LINE_DELIMITER);
150 			buffer.append(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptor_inferred_setting_pattern, setting));
151 		}
152 		return buffer.toString();
153 	}
154 
155 	/**
156 	 * Returns the number of settings.
157 	 *
158 	 * @return the number of settings
159 	 */
getCount()160 	public int getCount() {
161 		return fSettings.size();
162 	}
163 
164 	/**
165 	 * Initializes the inferred settings.
166 	 *
167 	 * @param object
168 	 *            the refactoring object
169 	 */
initializeInferredSettings(final Object object)170 	private void initializeInferredSettings(final Object object) {
171 		if (object instanceof INameUpdating) {
172 			final INameUpdating updating= (INameUpdating) object;
173 			fSettings.add(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptor_original_element_pattern, JavaElementLabelsCore.getTextLabel(updating.getElements()[0], JavaElementLabelsCore.ALL_FULLY_QUALIFIED)));
174 			try {
175 				final Object element= updating.getNewElement();
176 				if (element != null)
177 					fSettings.add(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptor_renamed_element_pattern, JavaElementLabelsCore.getTextLabel(element, JavaElementLabelsCore.ALL_FULLY_QUALIFIED)));
178 				else {
179 					final String newLabel= BasicElementLabels.getJavaElementName(updating.getCurrentElementName());
180 					fSettings.add(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptor_renamed_element_pattern, newLabel));
181 				}
182 			} catch (CoreException exception) {
183 				JavaManipulationPlugin.log(exception);
184 			}
185 		} else if (object instanceof RefactoringProcessor) {
186 			final RefactoringProcessor processor= (RefactoringProcessor) object;
187 			final Object[] elements= processor.getElements();
188 			if (elements != null) {
189 				if (elements.length == 1 && elements[0] != null)
190 					fSettings.add(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptor_original_element_pattern, JavaElementLabelsCore.getTextLabel(elements[0], JavaElementLabelsCore.ALL_FULLY_QUALIFIED)));
191 				else if (elements.length > 1) {
192 					final StringBuilder buffer= new StringBuilder(128);
193 					buffer.append(RefactoringCoreMessages.JavaRefactoringDescriptor_original_elements);
194 					for (Object element : elements) {
195 						if (element != null) {
196 							buffer.append(LINE_DELIMITER);
197 							buffer.append(ELEMENT_DELIMITER);
198 							buffer.append(JavaElementLabelsCore.getTextLabel(element, JavaElementLabelsCore.ALL_FULLY_QUALIFIED));
199 						} else {
200 							buffer.append(LINE_DELIMITER);
201 							buffer.append(ELEMENT_DELIMITER);
202 							buffer.append(RefactoringCoreMessages.JavaRefactoringDescriptor_not_available);
203 						}
204 					}
205 					fSettings.add(buffer.toString());
206 				}
207 			}
208 		} else if (object instanceof IReorgPolicy) {
209 			final IReorgPolicy policy= (IReorgPolicy) object;
210 			Object destination= policy.getJavaElementDestination();
211 			if (destination != null)
212 				fSettings.add(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptorComment_destination_pattern, JavaElementLabelsCore.getTextLabel(destination, JavaElementLabelsCore.ALL_FULLY_QUALIFIED)));
213 			else {
214 				destination= policy.getResourceDestination();
215 				if (destination != null)
216 					fSettings.add(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptorComment_destination_pattern, JavaElementLabelsCore.getTextLabel(destination, JavaElementLabelsCore.ALL_FULLY_QUALIFIED)));
217 			}
218 			final List<IAdaptable> list= new ArrayList<>();
219 			list.addAll(Arrays.asList(policy.getJavaElements()));
220 			list.addAll(Arrays.asList(policy.getResources()));
221 			final Object[] elements= list.toArray();
222 			if (elements != null) {
223 				if (elements.length == 1 && elements[0] != null)
224 					fSettings.add(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptor_original_element_pattern, JavaElementLabelsCore.getTextLabel(elements[0], JavaElementLabelsCore.ALL_FULLY_QUALIFIED)));
225 				else if (elements.length > 1) {
226 					final StringBuilder buffer= new StringBuilder(128);
227 					buffer.append(RefactoringCoreMessages.JavaRefactoringDescriptor_original_elements);
228 					for (Object element : elements) {
229 						if (element != null) {
230 							buffer.append(LINE_DELIMITER);
231 							buffer.append(ELEMENT_DELIMITER);
232 							buffer.append(JavaElementLabelsCore.getTextLabel(element, JavaElementLabelsCore.ALL_FULLY_QUALIFIED));
233 						} else {
234 							buffer.append(LINE_DELIMITER);
235 							buffer.append(ELEMENT_DELIMITER);
236 							buffer.append(RefactoringCoreMessages.JavaRefactoringDescriptor_not_available);
237 						}
238 					}
239 					fSettings.add(buffer.toString());
240 				}
241 			}
242 			if (object instanceof IMovePolicy) {
243 				final IMovePolicy extended= (IMovePolicy) object;
244 				if (extended.isTextualMove())
245 					fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptorComment_textual_move_only);
246 			}
247 		}
248 		if (object instanceof IReferenceUpdating) {
249 			final IReferenceUpdating updating= (IReferenceUpdating) object;
250 			if (updating.getUpdateReferences())
251 				fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptor_update_references);
252 		}
253 		if (object instanceof ISimilarDeclarationUpdating) {
254 			final ISimilarDeclarationUpdating updating= (ISimilarDeclarationUpdating) object;
255 			if (updating.canEnableSimilarDeclarationUpdating() && updating.getUpdateSimilarDeclarations()) {
256 				final int strategy= updating.getMatchStrategy();
257 				switch (strategy) {
258 				case RenamingNameSuggestor.STRATEGY_EXACT:
259 					fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptor_rename_similar);
260 					break;
261 				case RenamingNameSuggestor.STRATEGY_EMBEDDED:
262 					fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptor_rename_similar_embedded);
263 					break;
264 				case RenamingNameSuggestor.STRATEGY_SUFFIX:
265 					fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptor_rename_similar_suffix);
266 					break;
267 				default:
268 					break;
269 				}
270 			}
271 		}
272 		if (object instanceof IQualifiedNameUpdating) {
273 			final IQualifiedNameUpdating updating= (IQualifiedNameUpdating) object;
274 			if (updating.canEnableQualifiedNameUpdating() && updating.getUpdateQualifiedNames()) {
275 				final String patterns= updating.getFilePatterns();
276 				if (patterns != null && !"".equals(patterns)) //$NON-NLS-1$
277 					fSettings.add(Messages.format(RefactoringCoreMessages.JavaRefactoringDescriptor_qualified_names_pattern, BasicElementLabels.getFilePattern(patterns.trim())));
278 				else
279 					fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptor_qualified_names);
280 			}
281 		}
282 		if (object instanceof ITextUpdating) {
283 			final ITextUpdating updating= (ITextUpdating) object;
284 			if (updating.canEnableTextUpdating())
285 				fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptor_textual_occurrences);
286 		}
287 		if (object instanceof IDelegateUpdating) {
288 			final IDelegateUpdating updating= (IDelegateUpdating) object;
289 			if (updating.canEnableDelegateUpdating() && updating.getDelegateUpdating()) {
290 				if (updating.getDeprecateDelegates())
291 					fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptor_keep_original_deprecated);
292 				else
293 					fSettings.add(RefactoringCoreMessages.JavaRefactoringDescriptor_keep_original);
294 			}
295 		}
296 	}
297 
298 	/**
299 	 * Removes the setting at the specified index.
300 	 *
301 	 * @param index
302 	 *            the index
303 	 */
removeSetting(final int index)304 	public void removeSetting(final int index) {
305 		Assert.isTrue(index >= 0);
306 		fSettings.remove(index);
307 	}
308 }
309