001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.cnd.modelimpl.uid;
043:
044: import java.io.DataInput;
045: import java.io.DataOutput;
046: import java.io.IOException;
047: import java.util.concurrent.atomic.AtomicInteger;
048: import org.netbeans.modules.cnd.api.model.CsmBuiltIn;
049: import org.netbeans.modules.cnd.api.model.CsmClass;
050: import org.netbeans.modules.cnd.api.model.CsmClassifier;
051: import org.netbeans.modules.cnd.api.model.CsmFile;
052: import org.netbeans.modules.cnd.api.model.CsmInclude;
053: import org.netbeans.modules.cnd.api.model.CsmMacro;
054: import org.netbeans.modules.cnd.api.model.CsmNamespace;
055: import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration;
056: import org.netbeans.modules.cnd.api.model.CsmProject;
057: import org.netbeans.modules.cnd.api.model.CsmTypedef;
058: import org.netbeans.modules.cnd.api.model.CsmUID;
059: import org.netbeans.modules.cnd.api.model.util.CsmTracer;
060: import org.netbeans.modules.cnd.modelimpl.csm.core.FileImpl;
061: import org.netbeans.modules.cnd.modelimpl.csm.core.OffsetableDeclarationBase;
062: import org.netbeans.modules.cnd.modelimpl.csm.core.ProjectBase;
063: import org.netbeans.modules.cnd.modelimpl.debug.TraceFlags;
064: import org.netbeans.modules.cnd.modelimpl.repository.KeyUtilities;
065: import org.netbeans.modules.cnd.repository.spi.Key;
066: import org.netbeans.modules.cnd.repository.support.SelfPersistent;
067: import org.netbeans.modules.cnd.modelimpl.repository.PersistentUtils;
068:
069: /**
070: * utilities to create CsmUID for CsmObjects
071: * @author Vladimir Voskresensky
072: */
073: public class UIDUtilities {
074:
075: /** Creates a new instance of UIDUtilities */
076: private UIDUtilities() {
077: }
078:
079: public static CsmUID<CsmProject> createProjectUID(ProjectBase prj) {
080: return UIDManager.instance().getSharedUID(new ProjectUID(prj));
081: }
082:
083: public static CsmUID<CsmFile> createFileUID(FileImpl file) {
084: return UIDManager.instance().getSharedUID(new FileUID(file));
085: }
086:
087: public static CsmUID<CsmNamespace> createNamespaceUID(
088: CsmNamespace ns) {
089: return UIDManager.instance().getSharedUID(new NamespaceUID(ns));
090: }
091:
092: public static <T extends CsmOffsetableDeclaration> CsmUID<T> createDeclarationUID(
093: T declaration) {
094: assert (!(declaration instanceof CsmBuiltIn)) : "built-in have own UIDs";
095: CsmUID<T> uid;
096: if (!ProjectBase.canRegisterDeclaration(declaration)) {
097: uid = handleUnnamedDeclaration((CsmOffsetableDeclaration) declaration);
098: } else {
099: if (declaration instanceof CsmTypedef) {
100: uid = new TypedefUID((CsmTypedef) declaration);
101: } else if (declaration instanceof CsmClassifier) {
102: uid = new ClassifierUID(declaration);
103: } else {
104: uid = new DeclarationUID(declaration);
105: }
106: }
107: return UIDManager.instance().getSharedUID(uid);
108: }
109:
110: public static CsmUID<CsmMacro> createMacroUID(CsmMacro macro) {
111: return UIDManager.instance().getSharedUID(new MacroUID(macro));
112: }
113:
114: public static CsmUID<CsmInclude> createIncludeUID(CsmInclude incl) {
115: return UIDManager.instance().getSharedUID(new IncludeUID(incl));
116: }
117:
118: public static CsmUID<CsmClass> createUnresolvedClassUID(
119: String name, CsmProject project) {
120: return UIDManager.instance().getSharedUID(
121: new UnresolvedClassUID(name, project));
122: }
123:
124: public static CsmUID<CsmFile> createUnresolvedFileUID(
125: CsmProject project) {
126: return UIDManager.instance().getSharedUID(
127: new UnresolvedFileUID(project));
128: }
129:
130: public static CsmUID<CsmNamespace> createUnresolvedNamespaceUID(
131: CsmProject project) {
132: return UIDManager.instance().getSharedUID(
133: new UnresolvedNamespaceUID(project));
134: }
135:
136: private static CsmUID handleUnnamedDeclaration(
137: CsmOffsetableDeclaration decl) {
138: if (TraceFlags.TRACE_UNNAMED_DECLARATIONS) {
139: System.err.print("\n\ndeclaration with empty name '"
140: + decl.getUniqueName() + "'");
141: new CsmTracer().dumpModel(decl);
142: }
143: if (decl instanceof CsmClassifier) {
144: return new UnnamedClassifierUID(decl, UnnamedID
145: .incrementAndGet());
146: } else {
147: return new UnnamedOffsetableDeclarationUID(decl, UnnamedID
148: .incrementAndGet());
149: }
150: }
151:
152: private static AtomicInteger UnnamedID = new AtomicInteger(0);
153:
154: //////////////////////////////////////////////////////////////////////////
155: // impl details
156:
157: /**
158: * UID for CsmProject
159: */
160: /* package */static final class ProjectUID extends
161: KeyBasedUID<CsmProject> {
162: public ProjectUID(ProjectBase project) {
163: super (KeyUtilities.createProjectKey(project));
164: }
165:
166: /* package */ProjectUID(DataInput aStream) throws IOException {
167: super (aStream);
168: }
169: }
170:
171: /**
172: * UID for CsmNamespace
173: */
174: /* package */static final class NamespaceUID extends
175: KeyBasedUID<CsmNamespace> {
176: public NamespaceUID(CsmNamespace ns) {
177: super (KeyUtilities.createNamespaceKey(ns));
178: }
179:
180: /* package */NamespaceUID(DataInput aStream)
181: throws IOException {
182: super (aStream);
183: }
184: }
185:
186: /**
187: * UID for CsmFile
188: */
189: /* package */static final class FileUID extends
190: KeyBasedUID<CsmFile> {
191: public FileUID(FileImpl file) {
192: super (KeyUtilities.createFileKey(file));
193: }
194:
195: /* package */FileUID(DataInput aStream) throws IOException {
196: super (aStream);
197: }
198: }
199:
200: /**
201: * base UID for CsmDeclaration
202: */
203: private static abstract class OffsetableDeclarationUIDBase<T extends CsmOffsetableDeclaration>
204: extends KeyBasedUID<T> {
205: public OffsetableDeclarationUIDBase(T declaration) {
206: this (
207: KeyUtilities
208: .createOffsetableDeclarationKey((OffsetableDeclarationBase) declaration));
209: }
210:
211: protected OffsetableDeclarationUIDBase(Key key) {
212: super (key);
213: }
214:
215: /* package */OffsetableDeclarationUIDBase(DataInput aStream)
216: throws IOException {
217: super (aStream);
218: }
219:
220: @Override
221: public String toString() {
222: String retValue = getToStringPrefix() + ":"
223: + super .toString(); // NOI18N
224: return retValue;
225: }
226:
227: protected String getToStringPrefix() {
228: return "UID for OffsDecl"; // NOI18N
229: }
230: }
231:
232: /**
233: * UID for CsmTypedef
234: */
235: /* package */static final class TypedefUID<T extends CsmTypedef>
236: extends OffsetableDeclarationUIDBase<T> {
237: public TypedefUID(T typedef) {
238: super (typedef);
239: // assert typedef instanceof RegistarableDeclaration;
240: // if (!((RegistarableDeclaration)typedef).isRegistered()) {
241: // System.err.print("\n\nunregistered declaration'" + typedef.getUniqueName() + "'");
242: // new CsmTracer().dumpModel(typedef);
243: // }
244: // assert ((RegistarableDeclaration)typedef).isRegistered();
245: }
246:
247: /* package */TypedefUID(DataInput aStream) throws IOException {
248: super (aStream);
249: }
250:
251: @Override
252: protected String getToStringPrefix() {
253: return "TypedefUID"; // NOI18N
254: }
255:
256: }
257:
258: /**
259: * UID for CsmMacro
260: */
261: /* package */static final class MacroUID extends
262: KeyBasedUID<CsmMacro> {
263: public MacroUID(CsmMacro macro) {
264: super (KeyUtilities.createMacroKey(macro));
265: }
266:
267: /* package */MacroUID(DataInput aStream) throws IOException {
268: super (aStream);
269: }
270: }
271:
272: /**
273: * UID for CsmInclude
274: */
275: /* package */static final class IncludeUID extends
276: KeyBasedUID<CsmInclude> {
277: public IncludeUID(CsmInclude incl) {
278: super (KeyUtilities.createIncludeKey(incl));
279: }
280:
281: /* package */IncludeUID(DataInput aStream) throws IOException {
282: super (aStream);
283: }
284: }
285:
286: /**
287: * UID for CsmClassifier
288: */
289: /* package */static final class DeclarationUID<T extends CsmOffsetableDeclaration>
290: extends OffsetableDeclarationUIDBase<T> {
291: public DeclarationUID(T decl) {
292: super (decl);
293: }
294:
295: /* package */DeclarationUID(DataInput aStream)
296: throws IOException {
297: super (aStream);
298: }
299:
300: @Override
301: protected String getToStringPrefix() {
302: return "DeclarationUID"; // NOI18N
303: }
304:
305: }
306:
307: /**
308: * UID for CsmClassifier
309: */
310: /* package */static final class ClassifierUID<T extends CsmOffsetableDeclaration>
311: extends OffsetableDeclarationUIDBase<T> {
312: public ClassifierUID(T classifier) {
313: super (classifier);
314: }
315:
316: /* package */ClassifierUID(DataInput aStream)
317: throws IOException {
318: super (aStream);
319: }
320:
321: @Override
322: protected String getToStringPrefix() {
323: return "ClassifierUID"; // NOI18N
324: }
325:
326: }
327:
328: /**
329: * UID for CsmClassifier with empty getName()
330: */
331: /* package */static final class UnnamedClassifierUID<T extends CsmOffsetableDeclaration>
332: extends OffsetableDeclarationUIDBase<T> {
333: public UnnamedClassifierUID(T classifier, int index) {
334: super (KeyUtilities.createUnnamedOffsetableDeclarationKey(
335: (OffsetableDeclarationBase) classifier, index));
336: }
337:
338: /* package */UnnamedClassifierUID(DataInput aStream)
339: throws IOException {
340: super (aStream);
341: }
342:
343: @Override
344: protected String getToStringPrefix() {
345: return "<UNNAMED CLASSIFIER UID>"; // NOI18N
346: }
347: }
348:
349: /**
350: * UID for CsmDeclaration with empty getName()
351: */
352: /* package */static final class UnnamedOffsetableDeclarationUID<T extends CsmOffsetableDeclaration>
353: extends OffsetableDeclarationUIDBase<T> {
354: public UnnamedOffsetableDeclarationUID(T decl, int index) {
355: super (KeyUtilities.createUnnamedOffsetableDeclarationKey(
356: (OffsetableDeclarationBase) decl, index));
357: }
358:
359: /* package */UnnamedOffsetableDeclarationUID(DataInput aStream)
360: throws IOException {
361: super (aStream);
362: }
363:
364: @Override
365: protected String getToStringPrefix() {
366: return "<UNNAMED OFFS-DECL UID>"; // NOI18N
367: }
368: }
369:
370: /**
371: * Abstract base class for Unresolved* UIDs.
372: */
373: /* package */static abstract class UnresolvedUIDBase<T> implements
374: CsmUID<T>, SelfPersistent {
375:
376: private CsmUID<CsmProject> projectUID;
377:
378: public UnresolvedUIDBase(CsmProject project) {
379: projectUID = project.getUID();
380: }
381:
382: protected ProjectBase getProject() {
383: return (ProjectBase) projectUID.getObject();
384: }
385:
386: /* package */UnresolvedUIDBase(DataInput aStream)
387: throws IOException {
388: projectUID = UIDObjectFactory.getDefaultFactory().readUID(
389: aStream);
390: }
391:
392: public abstract T getObject();
393:
394: public void write(DataOutput output) throws IOException {
395: UIDObjectFactory.getDefaultFactory().writeUID(projectUID,
396: output);
397: }
398:
399: protected String getToStringPrefix() {
400: return "<UNRESOLVED UID>"; // NOI18N
401: }
402: }
403:
404: /* package */static final class UnresolvedClassUID<T> extends
405: UnresolvedUIDBase<CsmClass> {
406:
407: private String name;
408:
409: public UnresolvedClassUID(String name, CsmProject project) {
410: super (project);
411: this .name = name;
412: }
413:
414: public CsmClass getObject() {
415: return getProject().getDummyForUnresolved(name);
416: }
417:
418: public UnresolvedClassUID(DataInput input) throws IOException {
419: super (input);
420: name = PersistentUtils.readUTF(input);
421: }
422:
423: @Override
424: public void write(DataOutput output) throws IOException {
425: super .write(output);
426: PersistentUtils.writeUTF(name, output);
427: }
428:
429: }
430:
431: /* package */static final class UnresolvedNamespaceUID extends
432: UnresolvedUIDBase<CsmNamespace> {
433:
434: public UnresolvedNamespaceUID(CsmProject project) {
435: super (project);
436: }
437:
438: public UnresolvedNamespaceUID(DataInput input)
439: throws IOException {
440: super (input);
441: }
442:
443: public CsmNamespace getObject() {
444: return getProject().getUnresolvedNamespace();
445: }
446: }
447:
448: /* package */static final class UnresolvedFileUID extends
449: UnresolvedUIDBase<CsmFile> {
450:
451: public UnresolvedFileUID(CsmProject project) {
452: super (project);
453: }
454:
455: public UnresolvedFileUID(DataInput input) throws IOException {
456: super (input);
457: }
458:
459: public CsmFile getObject() {
460: return getProject().getUnresolvedFile();
461: }
462: }
463: }
|