001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.core;
011:
012: import java.util.HashMap;
013:
014: import org.eclipse.core.resources.IResource;
015: import org.eclipse.core.runtime.IPath;
016: import org.eclipse.core.runtime.IProgressMonitor;
017: import org.eclipse.jdt.core.*;
018: import org.eclipse.jdt.core.dom.ASTNode;
019: import org.eclipse.jdt.core.dom.CompilationUnit;
020: import org.eclipse.jdt.internal.core.util.DOMFinder;
021: import org.eclipse.jdt.internal.core.util.MementoTokenizer;
022: import org.eclipse.jdt.internal.core.util.Messages;
023:
024: /**
025: * Abstract class for Java elements which implement ISourceReference.
026: */
027: public abstract class SourceRefElement extends JavaElement implements
028: ISourceReference {
029: /*
030: * A count to uniquely identify this element in the case
031: * that a duplicate named element exists. For example, if
032: * there are two fields in a compilation unit with the
033: * same name, the occurrence count is used to distinguish
034: * them. The occurrence count starts at 1 (thus the first
035: * occurrence is occurrence 1, not occurrence 0).
036: */
037: public int occurrenceCount = 1;
038:
039: protected SourceRefElement(JavaElement parent) {
040: super (parent);
041: }
042:
043: /**
044: * This element is being closed. Do any necessary cleanup.
045: */
046: protected void closing(Object info) throws JavaModelException {
047: // Do any necessary cleanup
048: }
049:
050: /**
051: * Returns a new element info for this element.
052: */
053: protected Object createElementInfo() {
054: return null; // not used for source ref elements
055: }
056:
057: /**
058: * @see ISourceManipulation
059: */
060: public void copy(IJavaElement container, IJavaElement sibling,
061: String rename, boolean force, IProgressMonitor monitor)
062: throws JavaModelException {
063: if (container == null) {
064: throw new IllegalArgumentException(
065: Messages.operation_nullContainer);
066: }
067: IJavaElement[] elements = new IJavaElement[] { this };
068: IJavaElement[] containers = new IJavaElement[] { container };
069: IJavaElement[] siblings = null;
070: if (sibling != null) {
071: siblings = new IJavaElement[] { sibling };
072: }
073: String[] renamings = null;
074: if (rename != null) {
075: renamings = new String[] { rename };
076: }
077: getJavaModel().copy(elements, containers, siblings, renamings,
078: force, monitor);
079: }
080:
081: /**
082: * @see ISourceManipulation
083: */
084: public void delete(boolean force, IProgressMonitor monitor)
085: throws JavaModelException {
086: IJavaElement[] elements = new IJavaElement[] { this };
087: getJavaModel().delete(elements, force, monitor);
088: }
089:
090: public boolean equals(Object o) {
091: if (!(o instanceof SourceRefElement))
092: return false;
093: return this .occurrenceCount == ((SourceRefElement) o).occurrenceCount
094: && super .equals(o);
095: }
096:
097: /**
098: * Returns the <code>ASTNode</code> that corresponds to this <code>JavaElement</code>
099: * or <code>null</code> if there is no corresponding node.
100: */
101: public ASTNode findNode(CompilationUnit ast) {
102: DOMFinder finder = new DOMFinder(ast, this , false);
103: try {
104: return finder.search();
105: } catch (JavaModelException e) {
106: // receiver doesn't exist
107: return null;
108: }
109: }
110:
111: /*
112: * @see JavaElement#generateInfos
113: */
114: protected void generateInfos(Object info, HashMap newElements,
115: IProgressMonitor pm) throws JavaModelException {
116: Openable openableParent = (Openable) getOpenableParent();
117: if (openableParent == null)
118: return;
119:
120: JavaElementInfo openableParentInfo = (JavaElementInfo) JavaModelManager
121: .getJavaModelManager().getInfo(openableParent);
122: if (openableParentInfo == null) {
123: openableParent.generateInfos(openableParent
124: .createElementInfo(), newElements, pm);
125: }
126: }
127:
128: /**
129: * @see IMember
130: */
131: public ICompilationUnit getCompilationUnit() {
132: return (ICompilationUnit) getAncestor(COMPILATION_UNIT);
133: }
134:
135: /**
136: * Elements within compilation units and class files have no
137: * corresponding resource.
138: *
139: * @see IJavaElement
140: */
141: public IResource getCorrespondingResource()
142: throws JavaModelException {
143: if (!exists())
144: throw newNotPresentException();
145: return null;
146: }
147:
148: /*
149: * @see JavaElement
150: */
151: public IJavaElement getHandleFromMemento(String token,
152: MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
153: switch (token.charAt(0)) {
154: case JEM_COUNT:
155: return getHandleUpdatingCountFromMemento(memento,
156: workingCopyOwner);
157: }
158: return this ;
159: }
160:
161: protected void getHandleMemento(StringBuffer buff) {
162: super .getHandleMemento(buff);
163: if (this .occurrenceCount > 1) {
164: buff.append(JEM_COUNT);
165: buff.append(this .occurrenceCount);
166: }
167: }
168:
169: /*
170: * Update the occurence count of the receiver and creates a Java element handle from the given memento.
171: * The given working copy owner is used only for compilation unit handles.
172: */
173: public IJavaElement getHandleUpdatingCountFromMemento(
174: MementoTokenizer memento, WorkingCopyOwner owner) {
175: if (!memento.hasMoreTokens())
176: return this ;
177: this .occurrenceCount = Integer.parseInt(memento.nextToken());
178: if (!memento.hasMoreTokens())
179: return this ;
180: String token = memento.nextToken();
181: return getHandleFromMemento(token, memento, owner);
182: }
183:
184: /*
185: * @see IMember#getOccurrenceCount()
186: */
187: public int getOccurrenceCount() {
188: return this .occurrenceCount;
189: }
190:
191: /**
192: * Return the first instance of IOpenable in the hierarchy of this
193: * type (going up the hierarchy from this type);
194: */
195: public IOpenable getOpenableParent() {
196: IJavaElement current = getParent();
197: while (current != null) {
198: if (current instanceof IOpenable) {
199: return (IOpenable) current;
200: }
201: current = current.getParent();
202: }
203: return null;
204: }
205:
206: /*
207: * @see IJavaElement
208: */
209: public IPath getPath() {
210: return this .getParent().getPath();
211: }
212:
213: /*
214: * @see IJavaElement
215: */
216: public IResource getResource() {
217: return this .getParent().getResource();
218: }
219:
220: /**
221: * @see ISourceReference
222: */
223: public String getSource() throws JavaModelException {
224: IOpenable openable = getOpenableParent();
225: IBuffer buffer = openable.getBuffer();
226: if (buffer == null) {
227: return null;
228: }
229: ISourceRange range = getSourceRange();
230: int offset = range.getOffset();
231: int length = range.getLength();
232: if (offset == -1 || length == 0) {
233: return null;
234: }
235: try {
236: return buffer.getText(offset, length);
237: } catch (RuntimeException e) {
238: return null;
239: }
240: }
241:
242: /**
243: * @see ISourceReference
244: */
245: public ISourceRange getSourceRange() throws JavaModelException {
246: SourceRefElementInfo info = (SourceRefElementInfo) getElementInfo();
247: return info.getSourceRange();
248: }
249:
250: /**
251: * @see IJavaElement
252: */
253: public IResource getUnderlyingResource() throws JavaModelException {
254: if (!exists())
255: throw newNotPresentException();
256: return getParent().getUnderlyingResource();
257: }
258:
259: /**
260: * @see IParent
261: */
262: public boolean hasChildren() throws JavaModelException {
263: return getChildren().length > 0;
264: }
265:
266: /**
267: * @see IJavaElement
268: */
269: public boolean isStructureKnown() throws JavaModelException {
270: // structure is always known inside an openable
271: return true;
272: }
273:
274: /**
275: * @see ISourceManipulation
276: */
277: public void move(IJavaElement container, IJavaElement sibling,
278: String rename, boolean force, IProgressMonitor monitor)
279: throws JavaModelException {
280: if (container == null) {
281: throw new IllegalArgumentException(
282: Messages.operation_nullContainer);
283: }
284: IJavaElement[] elements = new IJavaElement[] { this };
285: IJavaElement[] containers = new IJavaElement[] { container };
286: IJavaElement[] siblings = null;
287: if (sibling != null) {
288: siblings = new IJavaElement[] { sibling };
289: }
290: String[] renamings = null;
291: if (rename != null) {
292: renamings = new String[] { rename };
293: }
294: getJavaModel().move(elements, containers, siblings, renamings,
295: force, monitor);
296: }
297:
298: /**
299: * @see ISourceManipulation
300: */
301: public void rename(String newName, boolean force,
302: IProgressMonitor monitor) throws JavaModelException {
303: if (newName == null) {
304: throw new IllegalArgumentException(
305: Messages.element_nullName);
306: }
307: IJavaElement[] elements = new IJavaElement[] { this };
308: IJavaElement[] dests = new IJavaElement[] { this .getParent() };
309: String[] renamings = new String[] { newName };
310: getJavaModel().rename(elements, dests, renamings, force,
311: monitor);
312: }
313:
314: protected void toStringName(StringBuffer buffer) {
315: super .toStringName(buffer);
316: if (this .occurrenceCount > 1) {
317: buffer.append("#"); //$NON-NLS-1$
318: buffer.append(this.occurrenceCount);
319: }
320: }
321: }
|