Source Code Cross Referenced for ProjectBase.java in  » IDE-Netbeans » cnd » org » netbeans » modules » cnd » modelimpl » csm » core » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » cnd » org.netbeans.modules.cnd.modelimpl.csm.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.modules.cnd.modelimpl.csm.core;
0043:
0044:        import java.io.DataInput;
0045:        import java.io.DataOutput;
0046:        import java.io.File;
0047:        import java.io.IOException;
0048:        import java.util.*;
0049:        import java.util.concurrent.ConcurrentHashMap;
0050:        import java.util.concurrent.locks.ReadWriteLock;
0051:        import java.util.concurrent.locks.ReentrantReadWriteLock;
0052:
0053:        import org.netbeans.modules.cnd.api.model.*;
0054:        import org.netbeans.modules.cnd.api.model.util.CsmTracer;
0055:        import org.netbeans.modules.cnd.api.project.NativeFileItem;
0056:        import org.netbeans.modules.cnd.api.project.NativeFileItem.Language;
0057:        import org.netbeans.modules.cnd.api.project.NativeProject;
0058:        import org.netbeans.modules.cnd.api.project.NativeProjectItemsListener;
0059:        import org.netbeans.modules.cnd.apt.debug.DebugUtils;
0060:        import org.netbeans.modules.cnd.apt.support.StartEntry;
0061:        import org.netbeans.modules.cnd.apt.support.APTHandlersSupport;
0062:        import org.netbeans.modules.cnd.apt.support.APTSystemStorage;
0063:        import org.netbeans.modules.cnd.apt.structure.APTFile;
0064:        import org.netbeans.modules.cnd.apt.support.APTDriver;
0065:        import org.netbeans.modules.cnd.apt.support.APTIncludeHandler;
0066:        import org.netbeans.modules.cnd.apt.support.APTMacroMap;
0067:        import org.netbeans.modules.cnd.apt.support.APTPreprocHandler;
0068:        import org.netbeans.modules.cnd.apt.support.APTWalker;
0069:        import org.netbeans.modules.cnd.modelimpl.cache.CacheManager;
0070:        import org.netbeans.modules.cnd.modelimpl.debug.Terminator;
0071:        import org.netbeans.modules.cnd.modelimpl.debug.Diagnostic;
0072:        import org.netbeans.modules.cnd.modelimpl.debug.TraceFlags;
0073:
0074:        import org.netbeans.modules.cnd.modelimpl.platform.*;
0075:        import org.netbeans.modules.cnd.modelimpl.csm.*;
0076:        import org.netbeans.modules.cnd.modelimpl.debug.DiagnosticExceptoins;
0077:        import org.netbeans.modules.cnd.modelimpl.parser.apt.APTParseFileWalker;
0078:        import org.netbeans.modules.cnd.modelimpl.parser.apt.APTRestorePreprocStateWalker;
0079:        import org.netbeans.modules.cnd.modelimpl.repository.KeyUtilities;
0080:        import org.netbeans.modules.cnd.modelimpl.repository.PersistentUtils;
0081:        import org.netbeans.modules.cnd.modelimpl.textcache.ProjectNameCache;
0082:        import org.netbeans.modules.cnd.modelimpl.textcache.QualifiedNameCache;
0083:        import org.netbeans.modules.cnd.modelimpl.repository.RepositoryUtils;
0084:        import org.netbeans.modules.cnd.modelimpl.uid.UIDCsmConverter;
0085:        import org.netbeans.modules.cnd.modelimpl.uid.UIDObjectFactory;
0086:        import org.netbeans.modules.cnd.modelimpl.uid.UIDUtilities;
0087:        import org.netbeans.modules.cnd.repository.spi.Key;
0088:        import org.netbeans.modules.cnd.repository.spi.Persistent;
0089:        import org.netbeans.modules.cnd.repository.support.SelfPersistent;
0090:        import org.netbeans.modules.cnd.utils.cache.CharSequenceKey;
0091:        import org.openide.util.Cancellable;
0092:
0093:        /**
0094:         * Base class for CsmProject implementation
0095:         * @author Dmitry Ivanov
0096:         * @author Vladimir Kvashin
0097:         */
0098:        public abstract class ProjectBase implements  CsmProject, Persistent,
0099:                SelfPersistent {
0100:
0101:            private transient boolean needParseOrphan;
0102:
0103:            /** Creates a new instance of CsmProjectImpl */
0104:            protected ProjectBase(ModelImpl model, Object platformProject,
0105:                    String name) {
0106:                setStatus(Status.Initial);
0107:                this .name = ProjectNameCache.getManager().getString(name);
0108:                init(model, platformProject);
0109:                NamespaceImpl ns = new NamespaceImpl(this );
0110:                assert ns != null;
0111:                this .globalNamespaceUID = UIDCsmConverter.namespaceToUID(ns);
0112:                declarationsSorageKey = new DeclarationContainer(this ).getKey();
0113:                fileContainerKey = new FileContainer(this ).getKey();
0114:                graphStorageKey = new GraphContainer(this ).getKey();
0115:            }
0116:
0117:            private void init(ModelImpl model, Object platformProject) {
0118:                this .model = model;
0119:                this .platformProject = platformProject;
0120:                // remember in repository
0121:                RepositoryUtils.hang(this );
0122:                // create global namespace
0123:
0124:                if (TraceFlags.CLOSE_AFTER_PARSE) {
0125:                    Terminator.create(this );
0126:                }
0127:                needParseOrphan = ModelSupport.needParseOrphan(platformProject);
0128:            }
0129:
0130:            private void setStatus(Status newStatus) {
0131:                //System.err.printf("CHANGING STATUS %s -> %s for %s (%s)\n", status, newStatus, name, getClass().getName());
0132:                status = newStatus;
0133:            }
0134:
0135:            protected static void cleanRepository(Object platformProject,
0136:                    boolean articicial) {
0137:                Key key = KeyUtilities.createProjectKey(getUniqueName(
0138:                        platformProject).toString());
0139:                RepositoryUtils.closeUnit(key, null, true);
0140:            }
0141:
0142:            public static ProjectBase readInstance(ModelImpl model,
0143:                    Object platformProject, String name) {
0144:
0145:                long time = 0;
0146:                if (TraceFlags.TIMING) {
0147:                    System.err.printf("Project %s: instantiating...\n", name);
0148:                    time = System.currentTimeMillis();
0149:                }
0150:
0151:                assert TraceFlags.PERSISTENT_REPOSITORY;
0152:                Key key = KeyUtilities.createProjectKey(getUniqueName(
0153:                        platformProject).toString());
0154:                RepositoryUtils.openUnit(key);
0155:                Persistent o = RepositoryUtils.get(key);
0156:                if (o != null) {
0157:                    assert o instanceof  ProjectBase;
0158:                    ProjectBase impl = (ProjectBase) o;
0159:                    if (!impl.name.equals(name)) {
0160:                        impl.setName(name);
0161:                    }
0162:                    impl.init(model, platformProject);
0163:                    if (TraceFlags.TIMING) {
0164:                        time = System.currentTimeMillis() - time;
0165:                        System.err.printf("Project %s: loaded. %d ms\n", name,
0166:                                time);
0167:                    }
0168:
0169:                    return impl;
0170:                }
0171:                return null;
0172:            }
0173:
0174:            public CsmNamespace getGlobalNamespace() {
0175:                return _getGlobalNamespace();
0176:            }
0177:
0178:            public CharSequence getName() {
0179:                return name;
0180:            }
0181:
0182:            protected void setName(String name) {
0183:                this .name = name;
0184:            }
0185:
0186:            /**
0187:             * Returns a string that uniquely identifies this project.
0188:             * One should never rely on this name structure, 
0189:             * just use it as in unique identifier
0190:             */
0191:            public CharSequence getUniqueName() {
0192:                if (this .uniqueName == null) {
0193:                    this .uniqueName = getUniqueName(getPlatformProject());
0194:                }
0195:                return this .uniqueName;
0196:            }
0197:
0198:            public static CharSequence getUniqueName(Object platformProject) {
0199:                String result;
0200:                if (platformProject instanceof  NativeProject) {
0201:                    result = ((NativeProject) platformProject).getProjectRoot() + 'N';
0202:                } else if (platformProject instanceof  String) {
0203:                    result = (String) platformProject + 'L';
0204:                } else if (platformProject == null) {
0205:                    throw new IllegalArgumentException(
0206:                            "Incorrect platform project: null"); // NOI18N
0207:                } else {
0208:                    throw new IllegalArgumentException(
0209:                            "Incorrect platform project class: "
0210:                                    + platformProject.getClass()); // NOI18N
0211:                }
0212:                return ProjectNameCache.getManager().getString(result);
0213:            }
0214:
0215:            /** Gets an object, which represents correspondent IDE project */
0216:            public Object getPlatformProject() {
0217:                return platformProject;
0218:            }
0219:
0220:            /** Gets an object, which represents correspondent IDE project */
0221:            protected void setPlatformProject(Object platformProject) {
0222:                this .platformProject = platformProject;
0223:                this .uniqueName = null;
0224:            }
0225:
0226:            /** Finds namespace by its qualified name */
0227:            public CsmNamespace findNamespace(String qualifiedName,
0228:                    boolean findInLibraries) {
0229:                CsmNamespace result = findNamespace(qualifiedName);
0230:                if (result == null && findInLibraries) {
0231:                    for (Iterator it = getLibraries().iterator(); it.hasNext();) {
0232:                        CsmProject lib = (CsmProject) it.next();
0233:                        result = lib.findNamespace(qualifiedName);
0234:                        if (result != null) {
0235:                            break;
0236:                        }
0237:                    }
0238:                }
0239:                return result;
0240:            }
0241:
0242:            /** Finds namespace by its qualified name */
0243:            public CsmNamespace findNamespace(CharSequence qualifiedName) {
0244:                CsmNamespace nsp = _getNamespace(qualifiedName);
0245:                return nsp;
0246:            }
0247:
0248:            public NamespaceImpl findNamespaceCreateIfNeeded(
0249:                    NamespaceImpl parent, CharSequence name) {
0250:                String qualifiedName = Utils.getNestedNamespaceQualifiedName(
0251:                        name, parent, true);
0252:                NamespaceImpl nsp = _getNamespace(qualifiedName);
0253:                if (nsp == null) {
0254:                    synchronized (namespaceLock) {
0255:                        nsp = _getNamespace(qualifiedName);
0256:                        if (nsp == null) {
0257:                            nsp = new NamespaceImpl(this , parent, name
0258:                                    .toString(), qualifiedName);
0259:                        }
0260:                    }
0261:                }
0262:                return nsp;
0263:            }
0264:
0265:            public void registerNamespace(NamespaceImpl namespace) {
0266:                _registerNamespace(namespace);
0267:            }
0268:
0269:            public void unregisterNamesace(NamespaceImpl namespace) {
0270:                _unregisterNamespace(namespace);
0271:            }
0272:
0273:            public CsmClassifier findClassifier(CharSequence qualifiedName,
0274:                    boolean findInLibraries) {
0275:                CsmClassifier result = findClassifier(qualifiedName);
0276:                if (result == null && findInLibraries) {
0277:                    for (Iterator it = getLibraries().iterator(); it.hasNext();) {
0278:                        CsmProject lib = (CsmProject) it.next();
0279:                        result = lib.findClassifier(qualifiedName);
0280:                        if (result != null) {
0281:                            break;
0282:                        }
0283:                    }
0284:                }
0285:                return result;
0286:            }
0287:
0288:            public CsmClassifier findClassifier(CharSequence qualifiedName) {
0289:                CsmClassifier result = classifierContainer
0290:                        .getClassifier(qualifiedName);
0291:                return result;
0292:            }
0293:
0294:            public CsmDeclaration findDeclaration(CharSequence uniqueName) {
0295:                return getDeclarationsSorage().getDeclaration(uniqueName);
0296:            }
0297:
0298:            public Collection<CsmOffsetableDeclaration> findDeclarations(
0299:                    CharSequence uniqueName) {
0300:                return getDeclarationsSorage().findDeclarations(uniqueName);
0301:            }
0302:
0303:            public Collection<CsmOffsetableDeclaration> findDeclarationsByPrefix(
0304:                    String prefix) {
0305:                return getDeclarationsSorage().getDeclarationsRange(prefix,
0306:                        prefix + "z"); // NOI18N
0307:            }
0308:
0309:            public Collection<CsmFriend> findFriendDeclarations(
0310:                    CsmOffsetableDeclaration decl) {
0311:                return getDeclarationsSorage().findFriends(decl);
0312:            }
0313:
0314:            public static boolean isCppFile(CsmFile file) {
0315:                return (file instanceof  FileImpl)
0316:                        && ((FileImpl) file).isCppFile();
0317:            }
0318:
0319:            //    public void registerClassifier(ClassEnumBase ce) {
0320:            //        classifiers.put(ce.getNestedNamespaceQualifiedName(), ce);
0321:            //        registerDeclaration(ce);
0322:            //    }
0323:
0324:            public static boolean canRegisterDeclaration(CsmDeclaration decl) {
0325:                // WAS: don't put unnamed declarations
0326:                assert decl != null;
0327:                assert decl.getName() != null;
0328:                if (decl.getName().length() == 0) {
0329:                    return false;
0330:                }
0331:                CsmScope scope = decl.getScope();
0332:                if (scope instanceof  CsmCompoundClassifier) {
0333:                    return canRegisterDeclaration((CsmCompoundClassifier) scope);
0334:                }
0335:                return true;
0336:            }
0337:
0338:            public void registerDeclaration(CsmOffsetableDeclaration decl) {
0339:
0340:                if (!ProjectBase.canRegisterDeclaration(decl)) {
0341:                    if (TraceFlags.TRACE_REGISTRATION) {
0342:                        System.err.println("not registered decl " + decl
0343:                                + " UID " + decl.getUID()); //NOI18N
0344:                    }
0345:
0346:                    return;
0347:                }
0348:                if (TraceFlags.CHECK_DECLARATIONS) {
0349:                    CsmDeclaration old = getDeclarationsSorage()
0350:                            .getDeclaration(decl.getUniqueName());
0351:                    if (old != null && old != decl) {
0352:                        System.err
0353:                                .println("\n\nRegistering different declaration with the same name:"
0354:                                        + decl.getUniqueName());
0355:                        System.err.print("WAS:");
0356:                        new CsmTracer().dumpModel(old);
0357:                        System.err.print("\nNOW:");
0358:                        new CsmTracer().dumpModel(decl);
0359:                    }
0360:                }
0361:                getDeclarationsSorage().putDeclaration(decl);
0362:
0363:                if (decl instanceof  CsmClassifier) {
0364:                    CharSequence qn = decl.getQualifiedName();
0365:                    if (!classifierContainer
0366:                            .putClassifier((CsmClassifier) decl)
0367:                            && TraceFlags.CHECK_DECLARATIONS) {
0368:                        CsmClassifier old = classifierContainer
0369:                                .getClassifier(qn);
0370:                        if (old != null && old != decl) {
0371:                            System.err
0372:                                    .println("\n\nRegistering different classifier with the same name:"
0373:                                            + qn);
0374:                            System.err.print("ALREADY EXISTS:");
0375:                            new CsmTracer().dumpModel(old);
0376:                            System.err.print("\nFAILED TO ADD:");
0377:                            new CsmTracer().dumpModel(decl);
0378:                        }
0379:                    }
0380:                }
0381:                if (TraceFlags.TRACE_REGISTRATION) {
0382:                    System.err.println("registered " + decl + " UID "
0383:                            + decl.getUID()); //NOI18N
0384:                }
0385:
0386:            }
0387:
0388:            public void unregisterDeclaration(CsmDeclaration decl) {
0389:                if (TraceFlags.TRACE_REGISTRATION) {
0390:                    System.err.println("unregistered " + decl + " UID "
0391:                            + decl.getUID()); //NOI18N
0392:                }
0393:                if (decl instanceof  CsmClassifier) {
0394:                    classifierContainer.removeClassifier(decl);
0395:                }
0396:                getDeclarationsSorage().removeDeclaration(decl);
0397:            }
0398:
0399:            public void waitParse() {
0400:                boolean insideParser = ParserThreadManager.instance()
0401:                        .isParserThread();
0402:                if (insideParser) {
0403:                    new Throwable(
0404:                            "project.waitParse should NEVER be called in parser thread !!!")
0405:                            .printStackTrace(System.err); // NOI18N
0406:                }
0407:                if (insideParser) {
0408:                    return;
0409:                }
0410:                ensureFilesCreated();
0411:                ensureChangedFilesEnqueued();
0412:                waitParseImpl();
0413:            }
0414:
0415:            private void waitParseImpl() {
0416:                synchronized (waitParseLock) {
0417:                    while (ParserQueue.instance().hasFiles(this , null)) {
0418:                        try {
0419:                            waitParseLock.wait();
0420:                        } catch (InterruptedException ex) {
0421:                            // do nothing
0422:                        }
0423:                    }
0424:                }
0425:            }
0426:
0427:            protected void ensureChangedFilesEnqueued() {
0428:            }
0429:
0430:            /**
0431:             * @param skipFile if null => check all files, otherwise skip checking
0432:             * this file
0433:             *
0434:             */
0435:            protected boolean hasChangedFiles(CsmFile skipFile) {
0436:                return false;
0437:            }
0438:
0439:            public boolean acceptNativeItem(NativeFileItem item) {
0440:                NativeFileItem.Language language = item.getLanguage();
0441:                return (language == NativeFileItem.Language.C
0442:                        || language == NativeFileItem.Language.CPP || language == NativeFileItem.Language.C_HEADER)
0443:                        && !item.isExcluded();
0444:            }
0445:
0446:            protected synchronized void ensureFilesCreated() {
0447:                if (status == Status.Initial || status == Status.Restored) {
0448:                    try {
0449:                        setStatus((status == Status.Initial) ? Status.AddingFiles
0450:                                : Status.Validating);
0451:                        long time = 0;
0452:                        if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
0453:                            System.err.println("suspend queue");
0454:                            ParserQueue.instance().suspend();
0455:                            if (TraceFlags.TIMING) {
0456:                                time = System.currentTimeMillis();
0457:                            }
0458:                        }
0459:                        ParserQueue.instance().onStartAddingProjectFiles(this );
0460:                        getModel().registerProjectListeners(this ,
0461:                                platformProject);
0462:                        NativeProject nativeProject = ModelSupport
0463:                                .getNativeProject(platformProject);
0464:                        if (nativeProject != null) {
0465:                            try {
0466:                                ParserQueue.instance().suspend();
0467:                                createProjectFilesIfNeed(nativeProject);
0468:                            } finally {
0469:                                ParserQueue.instance().resume();
0470:                            }
0471:                        }
0472:                        if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
0473:                            if (TraceFlags.TIMING) {
0474:                                time = System.currentTimeMillis() - time;
0475:                                System.err
0476:                                        .println("getting files from project system + put in queue took "
0477:                                                + time + "ms");
0478:                            }
0479:                            try {
0480:                                System.err.println("sleep for "
0481:                                        + TraceFlags.SUSPEND_PARSE_TIME
0482:                                        + "sec before resuming queue");
0483:                                Thread
0484:                                        .sleep(TraceFlags.SUSPEND_PARSE_TIME * 1000);
0485:                                System.err.println("woke up after sleep");
0486:                            } catch (InterruptedException ex) {
0487:                                // do nothing
0488:                            }
0489:                            ParserQueue.instance().resume();
0490:                        }
0491:                        ParserQueue.instance().onEndAddingProjectFiles(this );
0492:                    } finally {
0493:                        setStatus(Status.Ready);
0494:                    }
0495:                }
0496:            }
0497:
0498:            private void createProjectFilesIfNeed(NativeProject nativeProject) {
0499:
0500:                if (TraceFlags.TIMING) {
0501:                    System.err
0502:                            .printf(
0503:                                    "\n\nGetting files from project system for %s...\n",
0504:                                    getName());
0505:                }
0506:                if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
0507:                    try {
0508:                        System.err.println("sleep for "
0509:                                + TraceFlags.SUSPEND_PARSE_TIME
0510:                                + "sec before getting files from project");
0511:                        Thread.sleep(TraceFlags.SUSPEND_PARSE_TIME * 1000);
0512:                        System.err.println("woke up after sleep");
0513:                    } catch (InterruptedException ex) {
0514:                        // do nothing
0515:                    }
0516:                }
0517:                long time = System.currentTimeMillis();
0518:                final Set<NativeFileItem> removedFiles = Collections
0519:                        .synchronizedSet(new HashSet<NativeFileItem>());
0520:                NativeProjectItemsListener projectItemListener = new NativeProjectItemsListener() {
0521:                    public void fileAdded(NativeFileItem fileItem) {
0522:                    }
0523:
0524:                    public void filesAdded(List<NativeFileItem> fileItems) {
0525:                    }
0526:
0527:                    public void fileRemoved(NativeFileItem fileItem) {
0528:                        removedFiles.add(fileItem);
0529:                    }
0530:
0531:                    public void filesRemoved(List<NativeFileItem> fileItems) {
0532:                        removedFiles.addAll(fileItems);
0533:                    }
0534:
0535:                    public void fileRenamed(String oldPath,
0536:                            NativeFileItem newFileIetm) {
0537:                    }
0538:
0539:                    public void filePropertiesChanged(NativeFileItem fileItem) {
0540:                    }
0541:
0542:                    public void filesPropertiesChanged(
0543:                            List<NativeFileItem> fileItems) {
0544:                    }
0545:
0546:                    public void filesPropertiesChanged() {
0547:                    }
0548:
0549:                    public void projectDeleted(NativeProject nativeProject) {
0550:                    }
0551:                };
0552:                nativeProject.addProjectItemsListener(projectItemListener);
0553:                List<NativeFileItem> sources = new ArrayList<NativeFileItem>();
0554:                List<NativeFileItem> headers = new ArrayList<NativeFileItem>();
0555:                List<NativeFileItem> excluded = new ArrayList<NativeFileItem>();
0556:                for (NativeFileItem item : nativeProject.getAllFiles()) {
0557:                    if (!item.isExcluded()) {
0558:                        switch (item.getLanguage()) {
0559:                        case C:
0560:                        case CPP:
0561:                            sources.add(item);
0562:                            break;
0563:                        case C_HEADER:
0564:                            headers.add(item);
0565:                            break;
0566:                        default:
0567:                            break;
0568:                        }
0569:                    } else {
0570:                        switch (item.getLanguage()) {
0571:                        case C:
0572:                        case CPP:
0573:                        case C_HEADER:
0574:                            excluded.add(item);
0575:                            break;
0576:                        default:
0577:                            break;
0578:                        }
0579:                    }
0580:                }
0581:
0582:                if (TraceFlags.TIMING) {
0583:                    time = System.currentTimeMillis() - time;
0584:                    System.err
0585:                            .printf(
0586:                                    "Getting files from project system took  %d ms for %s\n",
0587:                                    time, getName());
0588:                    System.err
0589:                            .printf(
0590:                                    "FILES COUNT for %s:\nSource files:\t%d\nHeader files:\t%d\nTotal files:\t%d\n",
0591:                                    getName(), sources.size(), headers.size(),
0592:                                    sources.size() + headers.size());
0593:                    time = System.currentTimeMillis();
0594:                }
0595:                if (TraceFlags.SUSPEND_PARSE_TIME != 0) {
0596:                    try {
0597:                        System.err.println("sleep for "
0598:                                + TraceFlags.SUSPEND_PARSE_TIME
0599:                                + "sec after getting files from project");
0600:                        Thread.sleep(TraceFlags.SUSPEND_PARSE_TIME * 1000);
0601:                        System.err.println("woke up after sleep");
0602:                    } catch (InterruptedException ex) {
0603:                        // do nothing
0604:                    }
0605:                }
0606:                if (TraceFlags.DUMP_PROJECT_ON_OPEN) {
0607:                    ModelSupport.dumpNativeProject(nativeProject);
0608:                }
0609:
0610:                try {
0611:                    disposeLock.readLock().lock();
0612:
0613:                    if (TraceFlags.TIMING) {
0614:                        time = System.currentTimeMillis() - time;
0615:                        System.err.printf(
0616:                                "Waited on disposeLock: %d ms for %s\n", time,
0617:                                getName());
0618:                        time = System.currentTimeMillis();
0619:                    }
0620:
0621:                    if (disposing) {
0622:                        if (TraceFlags.TRACE_MODEL_STATE)
0623:                            System.err
0624:                                    .printf(
0625:                                            "filling parser queue interrupted for %s\n",
0626:                                            getName());
0627:                        return;
0628:                    }
0629:
0630:                    ProjectSettingsValidator validator = null;
0631:                    if (status == Status.Validating) {
0632:                        validator = new ProjectSettingsValidator(this );
0633:                        validator.restoreSettings();
0634:                    }
0635:                    projectRoots.fixFolder(nativeProject.getProjectRoot());
0636:                    for (String root : nativeProject.getSourceRoots()) {
0637:                        projectRoots.fixFolder(root);
0638:                    }
0639:                    projectRoots.addSources(sources);
0640:                    projectRoots.addSources(headers);
0641:                    projectRoots.addSources(excluded);
0642:                    createProjectFilesIfNeed(sources, true, removedFiles,
0643:                            validator);
0644:                    createProjectFilesIfNeed(headers, false, removedFiles,
0645:                            validator);
0646:
0647:                } finally {
0648:                    disposeLock.readLock().unlock();
0649:                    if (TraceFlags.TIMING) {
0650:                        time = System.currentTimeMillis() - time;
0651:                        System.err.printf(
0652:                                "FILLING PARSER QUEUE took %d ms for %s\n",
0653:                                time, getName());
0654:                    }
0655:                }
0656:                nativeProject.removeProjectItemsListener(projectItemListener);
0657:                // in fact if visitor used for parsing => visitor will parse all included files
0658:                // recursively starting from current source file
0659:                // so, when we visit headers, they should not be reparsed if already were parsed
0660:            }
0661:
0662:            private void createProjectFilesIfNeed(List<NativeFileItem> items,
0663:                    boolean sources, Set<NativeFileItem> removedFiles,
0664:                    ProjectSettingsValidator validator) {
0665:
0666:                for (NativeFileItem nativeFileItem : items) {
0667:                    if (disposing) {
0668:                        if (TraceFlags.TRACE_MODEL_STATE)
0669:                            System.err
0670:                                    .printf(
0671:                                            "filling parser queue interrupted for %s\n",
0672:                                            getName());
0673:                        return;
0674:                    }
0675:                    if (removedFiles.contains(nativeFileItem)) {
0676:                        continue;
0677:                    }
0678:                    assert (nativeFileItem.getFile() != null) : "native file item must have valid File object";
0679:                    if (TraceFlags.DEBUG)
0680:                        ModelSupport.trace(nativeFileItem);
0681:                    try {
0682:                        createIfNeed(nativeFileItem, sources, validator);
0683:                    } catch (Exception ex) {
0684:                        DiagnosticExceptoins.register(ex);
0685:                    }
0686:                }
0687:            }
0688:
0689:            /**
0690:             * Creates FileImpl instance for the given file item if it hasn/t yet been created.
0691:             * Is called when initializing the project or new file is added to project.
0692:             * Isn't intended to be used in #included file processing.
0693:             */
0694:            protected void createIfNeed(NativeFileItem nativeFile,
0695:                    boolean isSourceFile, ProjectSettingsValidator validator) {
0696:
0697:                assert (nativeFile != null && nativeFile.getFile() != null);
0698:                if (!acceptNativeItem(nativeFile)) {
0699:                    return;
0700:                }
0701:                File file = nativeFile.getFile();
0702:                APTPreprocHandler preprocHandler = createPreprocHandler(nativeFile);
0703:                assert preprocHandler != null;
0704:                int fileType = isSourceFile ? getFileType(nativeFile)
0705:                        : FileImpl.HEADER_FILE;
0706:
0707:                FileAndHandler fileAndHandler = createOrFindFileImpl(
0708:                        ModelSupport.getFileBuffer(file), nativeFile, fileType);
0709:
0710:                if (fileAndHandler.preprocHandler == null) {
0711:                    fileAndHandler.preprocHandler = createPreprocHandler(nativeFile);
0712:                }
0713:                if (isSourceFile || needParseOrphan) {
0714:                    ParserQueue.instance().addLast(fileAndHandler.fileImpl,
0715:                            fileAndHandler.preprocHandler.getState());
0716:                }
0717:
0718:                if (validator != null) {
0719:                    if (fileAndHandler.fileImpl.validate()) {
0720:                        if (validator.arePropertiesChanged(nativeFile)) {
0721:                            if (TraceFlags.TRACE_VALIDATION)
0722:                                System.err
0723:                                        .printf(
0724:                                                "Validation: %s properties are changed \n",
0725:                                                nativeFile.getFile()
0726:                                                        .getAbsolutePath());
0727:                            DeepReparsingUtils.reparseOnPropertyChanged(
0728:                                    nativeFile, this );
0729:                        }
0730:                        // clients should listen for ProjectLoaded instead
0731:                        //		else if( fileAndHandler.fileImpl.isParsed() ) {
0732:                        //		    //ProgressSupport.instance().fireFileParsingStarted(fileAndHandler.fileImpl);
0733:                        //		    ProgressSupport.instance().fireFileParsingFinished(fileAndHandler.fileImpl);
0734:                        //		}
0735:                    } else {
0736:                        if (TraceFlags.TRACE_VALIDATION)
0737:                            System.err.printf(
0738:                                    "Validation: file %s is changed\n",
0739:                                    nativeFile.getFile().getAbsolutePath());
0740:                        DeepReparsingUtils.reparseOnEdit(
0741:                                fileAndHandler.fileImpl, this , true);
0742:                    }
0743:                }
0744:            }
0745:
0746:            /**
0747:             * Is called after project is added to model
0748:             * and all listeners are notified
0749:             */
0750:            public final void onAddedToModel() {
0751:                final boolean isRestored = status == Status.Restored;
0752:                //System.err.printf("onAddedToModel isRestored=%b status=%s for %s (%s) \n", isRestored, status, name, getClass().getName());
0753:                if (status == Status.Initial || status == Status.Restored) {
0754:                    Runnable r = new Runnable() {
0755:                        public void run() {
0756:                            onAddedToModelImpl(isRestored);
0757:                            synchronized (initializationTaskLock) {
0758:                                initializationTask = null;
0759:                            }
0760:                        };
0761:                    };
0762:                    String text = (status == Status.Initial) ? "Filling parser queue for "
0763:                            : "Validating files for "; // NOI18N
0764:                    synchronized (initializationTaskLock) {
0765:                        initializationTask = ModelImpl.instance()
0766:                                .enqueueModelTask(r, text + getName());
0767:                    }
0768:                }
0769:            }
0770:
0771:            protected Status getStatus() {
0772:                return status;
0773:            }
0774:
0775:            protected void onAddedToModelImpl(boolean isRestored) {
0776:
0777:                if (disposing) {
0778:                    return;
0779:                }
0780:
0781:                try {
0782:                    disposeLock.readLock().lock();
0783:                    if (disposing) {
0784:                        return;
0785:                    }
0786:
0787:                    ensureFilesCreated();
0788:                    if (disposing) {
0789:                        return;
0790:                    }
0791:
0792:                    ensureChangedFilesEnqueued();
0793:                    if (disposing) {
0794:                        return;
0795:                    }
0796:                    Notificator.instance().flush();
0797:                } finally {
0798:                    disposeLock.readLock().unlock();
0799:                }
0800:
0801:                if (isRestored) {
0802:                    ProgressSupport.instance().fireProjectLoaded(
0803:                            ProjectBase.this );
0804:                }
0805:
0806:                try {
0807:                    disposeLock.readLock().lock();
0808:                    if (isRestored && !disposing) {
0809:                        // FIXUP for #109105 fix the reason instead!
0810:                        try {
0811:                            // TODO: refactor this - remove waiting here!
0812:                            // It was introduced in version 1.2.2.27.2.94.4.41
0813:                            // when validation was introduced
0814:                            waitParseImpl();
0815:                            checkForRemoved();
0816:                        } catch (Exception e) {
0817:                            DiagnosticExceptoins.register(e);
0818:                        }
0819:                    }
0820:                    if (disposing) {
0821:                        return;
0822:                    }
0823:                    Notificator.instance().flush();
0824:                } finally {
0825:                    disposeLock.readLock().unlock();
0826:                }
0827:            }
0828:
0829:            /**
0830:             * For the project that is restored from persistence,
0831:             * is called when 1-st time parsed.
0832:             * Cheks whether there are files in code model, that are removed from the project system
0833:             */
0834:            private void checkForRemoved() {
0835:
0836:                NativeProject nativeProject = (platformProject instanceof  NativeProject) ? (NativeProject) platformProject
0837:                        : null;
0838:
0839:                // we might just ask NativeProject to find file,
0840:                // but it's too ineffective; so we have to create a set of project files paths
0841:                Set<String> projectFiles = null;
0842:                if (nativeProject != null) {
0843:                    projectFiles = new HashSet<String>();
0844:                    for (NativeFileItem item : nativeProject.getAllFiles()) {
0845:                        if (!item.isExcluded()) {
0846:                            switch (item.getLanguage()) {
0847:                            case C:
0848:                            case CPP:
0849:                            case C_HEADER:
0850:                                projectFiles.add(item.getFile()
0851:                                        .getAbsolutePath());
0852:                                //this would be a workaround for #116706 Code assistance do not recognize changes in file
0853:                                //projectFiles.add(item.getFile().getCanonicalPath());
0854:                                break;
0855:                            default:
0856:                                break;
0857:                            }
0858:                        }
0859:                    }
0860:                }
0861:
0862:                Set<FileImpl> candidates = new HashSet<FileImpl>();
0863:                Set<FileImpl> removedPhysically = new HashSet<FileImpl>();
0864:                for (FileImpl file : getAllFileImpls()) {
0865:                    if (!file.getFile().exists()) {
0866:                        removedPhysically.add(file);
0867:                    } else if (projectFiles != null) { // they might be null for library
0868:                        if (!projectFiles.contains(file.getAbsolutePath())) {
0869:                            candidates.add(file);
0870:                        }
0871:                    }
0872:                }
0873:                for (FileImpl file : removedPhysically) {
0874:                    if (TraceFlags.TRACE_VALIDATION)
0875:                        System.err
0876:                                .printf(
0877:                                        "Validation: removing (physically deleted) %s\n",
0878:                                        file.getAbsolutePath()); //NOI18N
0879:                    onFileRemoved(file);
0880:                }
0881:                for (FileImpl file : candidates) {
0882:                    boolean remove = true;
0883:                    Set<CsmFile> parents = getGraphStorage().getParentFiles(
0884:                            file);
0885:                    for (CsmFile parent : parents) {
0886:                        if (!candidates.contains(parent)) {
0887:                            remove = false;
0888:                            break;
0889:                        }
0890:                    }
0891:                    if (remove) {
0892:                        if (TraceFlags.TRACE_VALIDATION)
0893:                            System.err
0894:                                    .printf(
0895:                                            "Validation: removing (removed from project) %s\n",
0896:                                            file.getAbsolutePath()); //NOI18N
0897:                        onFileRemoved(file);
0898:                    }
0899:                }
0900:            }
0901:
0902:            protected APTPreprocHandler createEmptyPreprocHandler(File file) {
0903:                StartEntry startEntry = new StartEntry(FileContainer
0904:                        .getFileKey(file, true), RepositoryUtils
0905:                        .UIDtoKey(getUID()));
0906:                return APTHandlersSupport.createEmptyPreprocHandler(startEntry);
0907:            }
0908:
0909:            protected APTPreprocHandler createPreprocHandler(
0910:                    NativeFileItem nativeFile) {
0911:                assert (nativeFile != null);
0912:                APTMacroMap macroMap = getMacroMap(nativeFile);
0913:                APTIncludeHandler inclHandler = getIncludeHandler(nativeFile);
0914:                APTPreprocHandler preprocHandler = APTHandlersSupport
0915:                        .createPreprocHandler(macroMap, inclHandler,
0916:                                isSourceFile(nativeFile));
0917:                return preprocHandler;
0918:            }
0919:
0920:            private APTIncludeHandler getIncludeHandler(
0921:                    NativeFileItem nativeFile) {
0922:                if (!isSourceFile(nativeFile)) {
0923:                    nativeFile = DefaultFileItem.toDefault(nativeFile);
0924:                }
0925:                List<String> userIncludePaths = nativeFile
0926:                        .getUserIncludePaths();
0927:                List<String> sysIncludePaths = nativeFile
0928:                        .getSystemIncludePaths();
0929:                sysIncludePaths = sysAPTData.getIncludes(sysIncludePaths
0930:                        .toString(), sysIncludePaths);
0931:                StartEntry startEntry = new StartEntry(FileContainer
0932:                        .getFileKey(nativeFile.getFile(), true),
0933:                        RepositoryUtils.UIDtoKey(getUID()));
0934:                return APTHandlersSupport.createIncludeHandler(startEntry,
0935:                        sysIncludePaths, userIncludePaths);
0936:            }
0937:
0938:            private APTMacroMap getMacroMap(NativeFileItem nativeFile) {
0939:                if (!isSourceFile(nativeFile)) {
0940:                    nativeFile = DefaultFileItem.toDefault(nativeFile);
0941:                }
0942:                List<String> userMacros = nativeFile.getUserMacroDefinitions();
0943:                List<String> sysMacros = nativeFile.getSystemMacroDefinitions();
0944:                APTMacroMap map = APTHandlersSupport.createMacroMap(
0945:                        getSysMacroMap(sysMacros), userMacros);
0946:                return map;
0947:            }
0948:
0949:            protected boolean isSourceFile(NativeFileItem nativeFile) {
0950:                int type = getFileType(nativeFile);
0951:                return type == FileImpl.SOURCE_CPP_FILE
0952:                        || type == FileImpl.SOURCE_C_FILE
0953:                        || type == FileImpl.SOURCE_FILE;
0954:                //return nativeFile.getSystemIncludePaths().size()>0;
0955:            }
0956:
0957:            protected static int getFileType(NativeFileItem nativeFile) {
0958:                switch (nativeFile.getLanguage()) {
0959:                case C:
0960:                    return FileImpl.SOURCE_C_FILE;
0961:                case CPP:
0962:                    return FileImpl.SOURCE_CPP_FILE;
0963:                case C_HEADER:
0964:                    return FileImpl.HEADER_FILE;
0965:                default:
0966:                    return FileImpl.UNDEFINED_FILE;
0967:                }
0968:            }
0969:
0970:            private APTMacroMap getSysMacroMap(List<String> sysMacros) {
0971:                //TODO: it's faster to use sysAPTData.getMacroMap(configID, sysMacros);
0972:                // but we need this ID to get somehow... how?
0973:                APTMacroMap map = sysAPTData.getMacroMap(sysMacros.toString(),
0974:                        sysMacros);
0975:                return map;
0976:            }
0977:
0978:            public final APTPreprocHandler getPreprocHandler(File file) {
0979:                APTPreprocHandler preprocHandler = createEmptyPreprocHandler(file);
0980:                APTPreprocHandler.State state = getPreprocState(file);
0981:                if (state != null) {
0982:                    if (state.isCleaned()) {
0983:                        return restorePreprocHandler(file, preprocHandler,
0984:                                state);
0985:                    } else {
0986:                        if (TRACE_PP_STATE_OUT)
0987:                            System.err.println("copying state for " + file);
0988:                        preprocHandler.setState(state);
0989:                        return preprocHandler;
0990:                    }
0991:                }
0992:                if (TRACE_PP_STATE_OUT)
0993:                    System.err.printf(
0994:                            "null state for %s, returning default one", file);
0995:                return preprocHandler;
0996:            }
0997:
0998:            public final APTPreprocHandler.State getPreprocState(
0999:                    FileImpl fileImpl) {
1000:                APTPreprocHandler.State state = null;
1001:                FileContainer fc = getFileContainer();
1002:                if (fc != null) {
1003:                    File file = fileImpl.getBuffer().getFile();
1004:                    state = fc.getPreprocState(file);
1005:                }
1006:                return state;
1007:            }
1008:
1009:            /**
1010:             * This method for testing purpose only. Used from TraceModel
1011:             */
1012:            public CsmFile testAPTParseFile(NativeFileItem item) {
1013:                APTPreprocHandler preprocHandler = this 
1014:                        .createPreprocHandler(item);
1015:                return findFile(item.getFile(), getFileType(item),
1016:                        preprocHandler, true, preprocHandler.getState(), item);
1017:            }
1018:
1019:            /**
1020:             * This method must be called only under stateLock, 
1021:             * to get state lock use
1022:             * Object stateLock = getFileContainer().getLock(file);
1023:             */
1024:            protected final void putPreprocState(File file,
1025:                    APTPreprocHandler.State state) {
1026:                if (state != null && !state.isCleaned()) {
1027:                    state = APTHandlersSupport.createCleanPreprocState(state);
1028:                }
1029:                getFileContainer().putPreprocState(file, state);
1030:            }
1031:
1032:            protected final APTPreprocHandler.State setChangedFileState(
1033:                    NativeFileItem nativeFile) {
1034:                APTPreprocHandler.State state;
1035:                state = createPreprocHandler(nativeFile).getState();
1036:                File file = nativeFile.getFile();
1037:                Object stateLock = getFileContainer().getLock(file);
1038:                synchronized (stateLock) {
1039:                    getFileContainer().invalidatePreprocState(file);
1040:                    putPreprocState(file, state);
1041:                }
1042:                return state;
1043:            }
1044:
1045:            protected APTPreprocHandler.State getPreprocState(File file) {
1046:                return getFileContainer().getPreprocState(file);
1047:            }
1048:
1049:            protected void invalidatePreprocState(File file) {
1050:                Object stateLock = getFileContainer().getLock(file);
1051:                synchronized (stateLock) {
1052:                    getFileContainer().invalidatePreprocState(file);
1053:                }
1054:            }
1055:
1056:            public void invalidateFiles() {
1057:                getFileContainer().clearState();
1058:                for (Iterator it = getLibraries().iterator(); it.hasNext();) {
1059:                    ProjectBase lib = (ProjectBase) it.next();
1060:                    lib.invalidateFiles();
1061:                }
1062:            }
1063:
1064:            /**
1065:             * called to inform that file was #included from another file with specific preprocHandler
1066:             *
1067:             * @param file included file path
1068:             * @param preprocHandler preprocHandler with which the file is including
1069:             * @param mode of walker forced onFileIncluded for #include directive
1070:             * @return true if it's first time of file including
1071:             *          false if file was included before
1072:             */
1073:            public final FileImpl onFileIncluded(ProjectBase base, String file,
1074:                    APTPreprocHandler preprocHandler, int mode)
1075:                    throws IOException {
1076:                try {
1077:                    disposeLock.readLock().lock();
1078:                    if (disposing) {
1079:                        return null;
1080:                    }
1081:                    FileImpl csmFile = findFile(new File(file),
1082:                            FileImpl.HEADER_FILE, preprocHandler, false, null,
1083:                            null);
1084:
1085:                    APTFile aptLight = getAPTLight(csmFile);
1086:
1087:                    if (csmFile != null && aptLight != null) {
1088:                        csmFile.initGuardIfNeeded(preprocHandler, aptLight);
1089:                    }
1090:
1091:                    APTPreprocHandler.State state = updateFileStateIfNeeded(
1092:                            csmFile, preprocHandler);
1093:
1094:                    // gather macro map from all includes
1095:                    if (aptLight != null) {
1096:                        APTParseFileWalker walker = new APTParseFileWalker(
1097:                                base, aptLight, csmFile, preprocHandler);
1098:                        walker.visit();
1099:                    }
1100:
1101:                    if (state != null && !isDisposing() && !base.isDisposing()) {
1102:                        scheduleIncludedFileParsing(csmFile, state);
1103:                    }
1104:                    return csmFile;
1105:                } finally {
1106:                    disposeLock.readLock().unlock();
1107:                }
1108:            }
1109:
1110:            //    protected boolean needScheduleParsing(FileImpl file, APTPreprocHandler preprocHandler) {
1111:            //        APTPreprocHandler.State curState = (APTPreprocHandler.State) filesHandlers.get(file);
1112:            //        if (curState != null && !curState.isStateCorrect() && preprocHandler != null && preprocHandler.isStateCorrect()) {
1113:            //            return true;
1114:            //        }
1115:            //        return !file.isParsingOrParsed() || !TraceFlags.APT_CHECK_GET_STATE ;
1116:            //    }
1117:
1118:            protected APTPreprocHandler.State updateFileStateIfNeeded(
1119:                    FileImpl csmFile, APTPreprocHandler preprocHandler) {
1120:                APTPreprocHandler.State state = null;
1121:                File file = csmFile.getBuffer().getFile();
1122:                Object stateLock = getFileContainer().getLock(file);
1123:                synchronized (stateLock) {
1124:                    if (csmFile.isNeedReparse(getPreprocState(file),
1125:                            preprocHandler)) {
1126:                        state = preprocHandler.getState();
1127:                        putPreprocState(file, state);
1128:                        // invalidate file
1129:                        csmFile.stateChanged(true);
1130:                    }
1131:                }
1132:                return state;
1133:            }
1134:
1135:            public ProjectBase findFileProject(CharSequence absPath) {
1136:                // check own files
1137:                // Wait while files are created. Otherwise project file will be recognized as library file.
1138:                ensureFilesCreated();
1139:                File file = new File(absPath.toString());
1140:                if (getFile(file) != null) {
1141:                    return this ;
1142:                } else {
1143:                    // else check in libs
1144:                    for (CsmProject prj : getLibraries()) {
1145:                        // Wait while files are created. Otherwise project file will be recognized as library file.
1146:                        ((ProjectBase) prj).ensureFilesCreated();
1147:                        if (((ProjectBase) prj).getFile(file) != null) {
1148:                            return (ProjectBase) prj;
1149:                        }
1150:                    }
1151:                }
1152:                return null;
1153:            }
1154:
1155:            public boolean isMySource(String includePath) {
1156:                return projectRoots.isMySource(includePath);
1157:            }
1158:
1159:            public abstract void onFileAdded(NativeFileItem nativeFile);
1160:
1161:            public abstract void onFileAdded(List<NativeFileItem> items);
1162:
1163:            //public abstract void onFileRemoved(NativeFileItem nativeFile);
1164:            public abstract void onFileRemoved(FileImpl fileImpl);
1165:
1166:            public abstract void onFileRemoved(List<NativeFileItem> items);
1167:
1168:            public abstract void onFilePropertyChanged(NativeFileItem nativeFile);
1169:
1170:            public abstract void onFilePropertyChanged(
1171:                    List<NativeFileItem> items);
1172:
1173:            protected abstract void scheduleIncludedFileParsing(
1174:                    FileImpl csmFile, APTPreprocHandler.State state);
1175:
1176:            public abstract NativeFileItem getNativeFileItem(
1177:                    CsmUID<CsmFile> file);
1178:
1179:            protected abstract void putNativeFileItem(CsmUID<CsmFile> file,
1180:                    NativeFileItem nativeFileItem);
1181:
1182:            protected abstract void removeNativeFileItem(CsmUID<CsmFile> file);
1183:
1184:            protected abstract void clearNativeFileContainer();
1185:
1186:            public void onFileRemoved(File nativeFile) {
1187:                onFileRemoved(getFile(nativeFile));
1188:            }
1189:
1190:            public CsmFile findFile(CharSequence absolutePath) {
1191:                File file = new File(absolutePath.toString());
1192:                APTPreprocHandler preprocHandler = null;
1193:                if (getPreprocState(file) == null) {
1194:                    NativeFileItem nativeFile = null;
1195:                    // Try to find native file
1196:                    if (getPlatformProject() instanceof  NativeProject) {
1197:                        NativeProject prj = (NativeProject) getPlatformProject();
1198:                        if (prj != null) {
1199:                            nativeFile = prj.findFileItem(file);
1200:                            if (nativeFile == null) {
1201:                                // if not belong to NB project => not our file
1202:                                return null;
1203:                                // nativeFile = new DefaultFileItem(prj, absolutePath);
1204:                            }
1205:                            if (!acceptNativeItem(nativeFile)) {
1206:                                return null;
1207:                            }
1208:                            preprocHandler = createPreprocHandler(nativeFile);
1209:                        }
1210:                    }
1211:                    if (preprocHandler != null) {
1212:                        return findFile(file, FileImpl.UNDEFINED_FILE,
1213:                                preprocHandler, true,
1214:                                preprocHandler.getState(), nativeFile);
1215:                    }
1216:                }
1217:                // if getPreprocState(file) isn't null, the file alreasy exists, so we may not pass nativeFile
1218:                return findFile(file, FileImpl.UNDEFINED_FILE, preprocHandler,
1219:                        true, null, null);
1220:            }
1221:
1222:            protected FileImpl findFile(File file, int fileType,
1223:                    APTPreprocHandler preprocHandler,
1224:                    boolean scheduleParseIfNeed,
1225:                    APTPreprocHandler.State initial,
1226:                    NativeFileItem nativeFileItem) {
1227:
1228:                FileImpl impl = getFile(file);
1229:                if (impl == null) {
1230:                    synchronized (getFileContainer()) {
1231:                        impl = getFile(file);
1232:                        if (impl == null) {
1233:                            preprocHandler = (preprocHandler == null) ? getPreprocHandler(file)
1234:                                    : preprocHandler;
1235:                            impl = new FileImpl(ModelSupport
1236:                                    .getFileBuffer(file), this , fileType,
1237:                                    nativeFileItem);
1238:                            if (nativeFileItem != null) {
1239:                                putNativeFileItem(impl.getUID(), nativeFileItem);
1240:                            }
1241:                            putFile(file, impl, initial);
1242:                            // NB: parse only after putting into a map
1243:                            if (scheduleParseIfNeed) {
1244:                                APTPreprocHandler.State ppState = preprocHandler == null ? null
1245:                                        : preprocHandler.getState();
1246:                                ParserQueue.instance().addLast(impl, ppState);
1247:                            }
1248:                        }
1249:                    }
1250:                }
1251:                if (fileType == FileImpl.SOURCE_FILE && !impl.isSourceFile()) {
1252:                    impl.setSourceFile();
1253:                } else if (fileType == FileImpl.HEADER_FILE
1254:                        && !impl.isHeaderFile()) {
1255:                    impl.setHeaderFile();
1256:                }
1257:                Object stateLock = getFileContainer().getLock(file);
1258:                synchronized (stateLock) {
1259:                    if (initial != null && getPreprocState(file) == null) {
1260:                        putPreprocState(file, initial);
1261:                    }
1262:                }
1263:                return impl;
1264:            }
1265:
1266:            //    protected FileImpl createOrFindFileImpl(final NativeFileItem nativeFile) {
1267:            //	File file = nativeFile.getFile();
1268:            //	assert file != null;
1269:            //	return createOrFindFileImpl(ModelSupport.instance().getFileBuffer(file), nativeFile);
1270:            //    }
1271:
1272:            protected FileImpl createOrFindFileImpl(final FileBuffer buf,
1273:                    final NativeFileItem nativeFile) {
1274:                return createOrFindFileImpl(buf, nativeFile,
1275:                        getFileType(nativeFile)).fileImpl;
1276:            }
1277:
1278:            private static class FileAndHandler {
1279:                public FileAndHandler(FileImpl fileImpl,
1280:                        APTPreprocHandler preprocHandler) {
1281:                    this .fileImpl = fileImpl;
1282:                    this .preprocHandler = preprocHandler;
1283:                }
1284:
1285:                public FileImpl fileImpl;
1286:                public APTPreprocHandler preprocHandler;
1287:            }
1288:
1289:            private FileAndHandler createOrFindFileImpl(final FileBuffer buf,
1290:                    final NativeFileItem nativeFile, int fileType) {
1291:                APTPreprocHandler preprocHandler = null;
1292:                File file = buf.getFile();
1293:                FileImpl impl = getFile(file);
1294:                if (impl == null) {
1295:                    synchronized (getFileContainer()) {
1296:                        impl = getFile(file);
1297:                        if (impl == null) {
1298:                            preprocHandler = createPreprocHandler(nativeFile);
1299:                            assert preprocHandler != null;
1300:                            impl = new FileImpl(buf, this , fileType, nativeFile);
1301:                            putFile(file, impl, preprocHandler.getState());
1302:                        } else {
1303:                            putNativeFileItem(impl.getUID(), nativeFile);
1304:                        }
1305:                    }
1306:                } else {
1307:                    putNativeFileItem(impl.getUID(), nativeFile);
1308:                }
1309:                return new FileAndHandler(impl, preprocHandler);
1310:            }
1311:
1312:            public FileImpl getFile(File file) {
1313:                return getFileContainer().getFile(file);
1314:            }
1315:
1316:            protected void removeFile(File file) {
1317:                getFileContainer().removeFile(file);
1318:            }
1319:
1320:            protected void putFile(File file, FileImpl impl,
1321:                    APTPreprocHandler.State state) {
1322:                if (state != null && !state.isCleaned()) {
1323:                    state = APTHandlersSupport.createCleanPreprocState(state);
1324:                }
1325:                getFileContainer().putFile(file, impl, state);
1326:            }
1327:
1328:            protected Collection<Key> getLibrariesKeys() {
1329:                List<Key> res = new ArrayList<Key>();
1330:                if (platformProject instanceof  NativeProject) {
1331:                    for (NativeProject nativeLib : ((NativeProject) platformProject)
1332:                            .getDependences()) {
1333:                        final Key key = KeyUtilities
1334:                                .createProjectKey(getUniqueName(nativeLib)
1335:                                        .toString());
1336:                        if (key != null) {
1337:                            res.add(key);
1338:                        }
1339:                    }
1340:                }
1341:                // Last dependent project is common library.
1342:                //final Key lib = KeyUtilities.createProjectKey("/usr/include"); // NOI18N
1343:                //if (lib != null) {
1344:                //    res.add(lib);
1345:                //}
1346:                if (!isArtificial()) {
1347:                    for (CsmUID<CsmProject> library : LibraryManager
1348:                            .getInstance().getLirariesKeys(getUID())) {
1349:                        res.add(RepositoryUtils.UIDtoKey(library));
1350:                    }
1351:                }
1352:                return res;
1353:            }
1354:
1355:            public Collection<CsmProject> getLibraries() {
1356:                List<CsmProject> res = new ArrayList<CsmProject>();
1357:                if (platformProject instanceof  NativeProject) {
1358:                    for (NativeProject nativeLib : ((NativeProject) platformProject)
1359:                            .getDependences()) {
1360:                        CsmProject prj = model.findProject(nativeLib);
1361:                        if (prj != null) {
1362:                            res.add(prj);
1363:                        }
1364:                    }
1365:                }
1366:                // Last dependent project is common library.
1367:                //ProjectBase lib = getModel().getLibrary("/usr/include"); // NOI18N
1368:                //if (lib != null) {
1369:                //    res.add(lib);
1370:                //}
1371:                if (!isArtificial()) {
1372:                    for (LibProjectImpl library : LibraryManager.getInstance()
1373:                            .getLiraries((ProjectImpl) this )) {
1374:                        res.add(library);
1375:                    }
1376:                }
1377:                return res;
1378:            }
1379:
1380:            public List<ProjectBase> getDependentProjects() {
1381:                List<ProjectBase> res = new ArrayList<ProjectBase>();
1382:                for (CsmProject prj : model.projects()) {
1383:                    if (prj instanceof  ProjectBase) {
1384:                        if (prj.getLibraries().contains(this )) {
1385:                            res.add((ProjectBase) prj);
1386:                        }
1387:                    }
1388:                }
1389:                return res;
1390:            }
1391:
1392:            /**
1393:             * Creates a dummy ClassImpl for uresolved name, stores in map
1394:             * @param nameTokens name
1395:             * @param file file that contains unresolved name (used for the purpose of statictics)
1396:             * @param name offset that contains unresolved name (used for the purpose of statictics)
1397:             */
1398:            public CsmClass getDummyForUnresolved(CharSequence[] nameTokens,
1399:                    CsmFile file, int offset) {
1400:                if (Diagnostic.needStatistics())
1401:                    Diagnostic.onUnresolvedError(nameTokens, file, offset);
1402:                return getUnresolved().getDummyForUnresolved(nameTokens);
1403:            }
1404:
1405:            /**
1406:             * Creates a dummy ClassImpl for uresolved name, stores in map.
1407:             * Should be used only when restoring from persistence:
1408:             * in contrary to getDummyForUnresolved(String[] nameTokens, CsmFile file, int offset),
1409:             * it does not gather statistics!
1410:             * @param nameTokens name
1411:             */
1412:            public CsmClass getDummyForUnresolved(String name) {
1413:                return getUnresolved().getDummyForUnresolved(name);
1414:            }
1415:
1416:            public CsmNamespace getUnresolvedNamespace() {
1417:                return getUnresolved().getUnresolvedNamespace();
1418:            }
1419:
1420:            public CsmFile getUnresolvedFile() {
1421:                return getUnresolved().getUnresolvedFile();
1422:            }
1423:
1424:            private Unresolved getUnresolved() {
1425:                // we don't sinc here since this isn't important enough:
1426:                // at worst a map with one or two dummies will be thrown away
1427:                if (unresolved == null) {
1428:                    unresolved = new Unresolved(this );
1429:                }
1430:                return unresolved;
1431:            }
1432:
1433:            public boolean isValid() {
1434:                return platformProject != null && !disposing;
1435:            }
1436:
1437:            public void setDisposed() {
1438:                disposing = true;
1439:                synchronized (initializationTaskLock) {
1440:                    if (initializationTask != null) {
1441:                        initializationTask.cancel();
1442:                        initializationTask = null;
1443:                    }
1444:                }
1445:                ParserQueue.instance().removeAll(this );
1446:            }
1447:
1448:            public boolean isDisposing() {
1449:                return disposing;
1450:            }
1451:
1452:            public void dispose(final boolean cleanPersistent) {
1453:
1454:                long time = 0;
1455:                if (TraceFlags.TIMING) {
1456:                    System.err.printf("\n\nProject %s: disposing...\n", name);
1457:                    time = System.currentTimeMillis();
1458:                }
1459:
1460:                // just in case it wasn't called before (it's inexpensive)
1461:                setDisposed();
1462:
1463:                try {
1464:
1465:                    disposeLock.writeLock().lock();
1466:
1467:                    ProjectSettingsValidator validator = new ProjectSettingsValidator(
1468:                            this );
1469:                    validator.storeSettings();
1470:                    RepositoryUtils.closeUnit(getUID(), getRequiredUnits(),
1471:                            cleanPersistent);
1472:
1473:                    platformProject = null;
1474:                    unresolved = null;
1475:                    uid = null;
1476:                } finally {
1477:                    disposeLock.writeLock().unlock();
1478:                }
1479:
1480:                if (TraceFlags.TIMING) {
1481:                    time = System.currentTimeMillis() - time;
1482:                    System.err.printf("Project %s: disposing took %d ms\n",
1483:                            name, time);
1484:                }
1485:            }
1486:
1487:            protected Set<String> getRequiredUnits() {
1488:                Set<String> requiredUnits = new HashSet<String>();
1489:                for (Key dependent : this .getLibrariesKeys()) {
1490:                    requiredUnits.add(dependent.getUnit().toString());
1491:                }
1492:                return requiredUnits;
1493:            }
1494:
1495:            private void disposeFiles() {
1496:                List<FileImpl> list;
1497:                //        synchronized (fileContainer) {
1498:                list = getFileContainer().getFileImpls();
1499:                getFileContainer().clear();
1500:                //        }
1501:                for (FileImpl file : list) {
1502:                    file.onProjectDispose();
1503:                    if (TraceFlags.USE_AST_CACHE) {
1504:                        CacheManager.getInstance().invalidate(file);
1505:                    } else {
1506:                        APTDriver.getInstance().invalidateAPT(file.getBuffer());
1507:                    }
1508:                }
1509:                clearNativeFileContainer();
1510:            }
1511:
1512:            private NamespaceImpl _getGlobalNamespace() {
1513:                NamespaceImpl ns = (NamespaceImpl) UIDCsmConverter
1514:                        .UIDtoNamespace(globalNamespaceUID);
1515:                assert ns != null : "Failed to get global namespace by key "
1516:                        + globalNamespaceUID;
1517:                return ns;
1518:            }
1519:
1520:            private NamespaceImpl _getNamespace(CharSequence key) {
1521:                key = CharSequenceKey.create(key);
1522:                CsmUID<CsmNamespace> nsUID = namespaces.get(key);
1523:                NamespaceImpl ns = (NamespaceImpl) UIDCsmConverter
1524:                        .UIDtoNamespace(nsUID);
1525:                return ns;
1526:            }
1527:
1528:            private void _registerNamespace(NamespaceImpl ns) {
1529:                assert (ns != null);
1530:                CharSequence key = ns.getQualifiedName();
1531:                assert (key != null && !(key instanceof  String));
1532:                CsmUID<CsmNamespace> nsUID = RepositoryUtils.put(ns);
1533:                assert nsUID != null;
1534:                namespaces.put(key, nsUID);
1535:            }
1536:
1537:            private void _unregisterNamespace(NamespaceImpl ns) {
1538:                assert (ns != null);
1539:                assert !ns.isGlobal();
1540:                CharSequence key = ns.getQualifiedName();
1541:                assert (key != null && !(key instanceof  String));
1542:                CsmUID<CsmNamespace> nsUID = namespaces.remove(key);
1543:                assert nsUID != null;
1544:                RepositoryUtils.remove(nsUID);
1545:            }
1546:
1547:            protected ModelImpl getModel() {
1548:                return model;
1549:            }
1550:
1551:            public void onFileEditStart(FileBuffer buf,
1552:                    NativeFileItem nativeFile) {
1553:            }
1554:
1555:            public void onFileEditEnd(FileBuffer buf, NativeFileItem nativeFile) {
1556:            }
1557:
1558:            private CsmUID<CsmProject> uid = null;
1559:
1560:            public final CsmUID<CsmProject> getUID() { // final because called from constructor
1561:                if (uid == null) {
1562:                    uid = UIDUtilities.createProjectUID(this );
1563:                }
1564:                return uid;
1565:            }
1566:
1567:            public boolean isStable(CsmFile skipFile) {
1568:                if (status == Status.Ready && !disposing) {
1569:                    return !ParserQueue.instance().hasFiles(this ,
1570:                            (FileImpl) skipFile);
1571:                }
1572:                return false;
1573:            }
1574:
1575:            public void onParseFinish() {
1576:                synchronized (waitParseLock) {
1577:                    waitParseLock.notifyAll();
1578:                }
1579:                // it's ok to move the entire sycle into synchronized block,
1580:                // because from inter-session persistence point of view,
1581:                // if we don't fix fakes, we'll later consider that files are ok,
1582:                // which is incorrect if there are some fakes
1583:                try {
1584:                    disposeLock.readLock().lock();
1585:
1586:                    if (!disposing) {
1587:                        for (Iterator it = getAllFiles().iterator(); it
1588:                                .hasNext();) {
1589:                            FileImpl file = (FileImpl) it.next();
1590:                            file.fixFakeRegistrations();
1591:                        }
1592:                    }
1593:                } finally {
1594:                    disposeLock.readLock().unlock();
1595:                    ProjectComponent.setStable(declarationsSorageKey);
1596:                    ProjectComponent.setStable(fileContainerKey);
1597:                    ProjectComponent.setStable(graphStorageKey);
1598:                }
1599:            }
1600:
1601:            /**
1602:             * CsmProject implementation
1603:             */
1604:            public Collection<CsmFile> getAllFiles() {
1605:                return (Collection<CsmFile>) getFileContainer().getFiles();
1606:            }
1607:
1608:            /**
1609:             * We'd better name this getFiles();
1610:             * but unfortunately there already is such method,
1611:             * and it is used intensively
1612:             */
1613:            public Collection<FileImpl> getAllFileImpls() {
1614:                return getFileContainer().getFileImpls();
1615:            }
1616:
1617:            public Collection<CsmFile> getSourceFiles() {
1618:                List<CsmFile> res = new ArrayList<CsmFile>();
1619:                for (FileImpl file : getAllFileImpls()) {
1620:                    if (file.isSourceFile()) {
1621:                        res.add(file);
1622:                    }
1623:                }
1624:                return res;
1625:            }
1626:
1627:            public Collection<CsmFile> getHeaderFiles() {
1628:                List<CsmFile> res = new ArrayList<CsmFile>();
1629:                for (FileImpl file : getAllFileImpls()) {
1630:                    //if (file.isHeaderFile()) {
1631:                    if (!file.isSourceFile()) {
1632:                        res.add(file);
1633:                    }
1634:                }
1635:                return res;
1636:            }
1637:
1638:            public long getMemoryUsageEstimation() {
1639:                //TODO: replace with some smart algorythm
1640:                return getFileContainer().getSize();
1641:            }
1642:
1643:            @Override
1644:            public String toString() {
1645:                return getName().toString() + ' ' + getClass().getName() + " @"
1646:                        + hashCode(); // NOI18N
1647:            }
1648:
1649:            /** 
1650:             * Just a struct for the getStartEntryInfo return valie:
1651:             * if java allowed passing pointers by reference, we won't create this...
1652:             */
1653:            private static class /*struct*/StartEntryInfo {
1654:
1655:                public final APTPreprocHandler preprocHandler;
1656:                public final ProjectBase startProject;
1657:                public final FileImpl csmFile;
1658:
1659:                public StartEntryInfo(APTPreprocHandler preprocHandler,
1660:                        ProjectBase startProject, FileImpl csmFile) {
1661:                    this .preprocHandler = preprocHandler;
1662:                    this .startProject = startProject;
1663:                    this .csmFile = csmFile;
1664:                }
1665:
1666:            }
1667:
1668:            private StartEntryInfo getStartEntryInfo(
1669:                    APTPreprocHandler preprocHandler,
1670:                    APTPreprocHandler.State state) {
1671:                StartEntry startEntry = APTHandlersSupport
1672:                        .extractStartEntry(state);
1673:                ProjectBase startProject = getStartProject(startEntry);
1674:                FileImpl csmFile = startProject == null ? null : startProject
1675:                        .getFile(new File(startEntry.getStartFile()));
1676:                if (csmFile != null) {
1677:                    NativeFileItem nativeFile = csmFile.getNativeFileItem();
1678:                    if (nativeFile != null) {
1679:                        preprocHandler = startProject
1680:                                .createPreprocHandler(nativeFile);
1681:                    }
1682:                }
1683:                return new StartEntryInfo(preprocHandler, startProject, csmFile);
1684:            }
1685:
1686:            private APTPreprocHandler restorePreprocHandler(
1687:                    File interestedFile, APTPreprocHandler preprocHandler,
1688:                    APTPreprocHandler.State state) {
1689:                assert state != null;
1690:                assert state.isCleaned();
1691:                // walk through include stack to restore preproc information
1692:                List<APTIncludeHandler.IncludeInfo> reverseInclStack = APTHandlersSupport
1693:                        .extractIncludeStack(state);
1694:                assert (reverseInclStack != null);
1695:                if (reverseInclStack.isEmpty()) {
1696:                    if (TRACE_PP_STATE_OUT)
1697:                        System.err
1698:                                .println("stack is empty; return default for "
1699:                                        + interestedFile);
1700:                    return getStartEntryInfo(preprocHandler, state).preprocHandler;
1701:                } else {
1702:                    if (TRACE_PP_STATE_OUT)
1703:                        System.err.println("restoring for " + interestedFile);
1704:                    // we need to reverse includes stack
1705:                    assert (!reverseInclStack.isEmpty()) : "state of stack is "
1706:                            + reverseInclStack;
1707:                    Stack<APTIncludeHandler.IncludeInfo> inclStack = reverse(reverseInclStack);
1708:                    StartEntryInfo sei = getStartEntryInfo(preprocHandler,
1709:                            state);
1710:                    FileImpl csmFile = sei.csmFile;
1711:                    ProjectBase startProject = sei.startProject;
1712:                    preprocHandler = sei.preprocHandler;
1713:
1714:                    APTFile aptLight = null;
1715:                    try {
1716:                        aptLight = csmFile == null ? null
1717:                                : getAPTLight(csmFile);
1718:                    } catch (IOException ex) {
1719:                        System.err
1720:                                .println("can't restore preprocessor state for "
1721:                                        + interestedFile + //NOI18N
1722:                                        "\nreason: " + ex.getMessage());//NOI18N
1723:                        DiagnosticExceptoins.register(ex);
1724:                    }
1725:                    boolean ppStateRestored = false;
1726:                    if (aptLight != null) {
1727:                        // for testing remember restored file
1728:                        long time = REMEMBER_RESTORED ? System
1729:                                .currentTimeMillis() : 0;
1730:                        int stackSize = inclStack.size();
1731:                        APTWalker walker = new APTRestorePreprocStateWalker(
1732:                                startProject, aptLight, csmFile,
1733:                                preprocHandler, inclStack, FileContainer
1734:                                        .getFileKey(interestedFile, false));
1735:                        walker.visit();
1736:                        if (preprocHandler.isValid()) {
1737:                            if (REMEMBER_RESTORED) {
1738:                                if (testRestoredFiles == null) {
1739:                                    testRestoredFiles = new ArrayList<String>();
1740:                                }
1741:                                FileImpl interestedFileImpl = getFile(interestedFile);
1742:                                assert interestedFileImpl != null;
1743:                                String msg = interestedFile.getAbsolutePath()
1744:                                        + " ["
1745:                                        + (interestedFileImpl.isHeaderFile() ? "H"
1746:                                                : interestedFileImpl
1747:                                                        .isSourceFile() ? "S"
1748:                                                        : "U") + "]"; // NOI18N
1749:                                time = System.currentTimeMillis() - time;
1750:                                msg = msg + " within " + time + "ms"
1751:                                        + " stack " + stackSize + " elems"; // NOI18N
1752:                                System.err.println("#"
1753:                                        + testRestoredFiles.size()
1754:                                        + " restored: " + msg); // NOI18N
1755:                                testRestoredFiles.add(msg);
1756:                            }
1757:                            if (TRACE_PP_STATE_OUT) {
1758:                                System.err.println("after restoring "
1759:                                        + preprocHandler); // NOI18N
1760:                            }
1761:                            ppStateRestored = true;
1762:                        }
1763:                    }
1764:                    if (!ppStateRestored) {
1765:                        // need to recover from the problem, when start file is invalid or absent
1766:                        // try to find project who can create default handler with correct
1767:                        // compiler settings
1768:                        // preferences is start project
1769:                        if (startProject == null) {
1770:                            // otherwise use the project owner
1771:                            startProject = this ;
1772:                        }
1773:                        preprocHandler = startProject
1774:                                .createDefaultPreprocHandler(interestedFile);
1775:                        // remember
1776:                        // TODO: file container should accept all without checks
1777:                        // otherwise state will not be replaced
1778:                        //                synchronized (getFileContainer().getLock(interestedFile)) {
1779:                        //                    if (state.equals(getPreprocState(interestedFile))) {
1780:                        //                        APTPreprocHandler.State recoveredState = preprocHandler.getState();
1781:                        //                        assert !recoveredState.isCompileContext();
1782:                        //                        putPreprocState(interestedFile, recoveredState);
1783:                        //                    }
1784:                        //                }
1785:                    }
1786:                    return preprocHandler;
1787:                }
1788:            }
1789:
1790:            /*
1791:             private APTPreprocHandler restorePreprocHandler(File interestedFile, APTPreprocHandler preprocHandler, APTPreprocHandler.State state) {
1792:             assert state != null;
1793:             assert state.isCleaned();
1794:             // walk through include stack to restore preproc information
1795:             List<APTIncludeHandler.IncludeInfo> reverseInclStack = APTHandlersSupport.extractIncludeStack(state);
1796:             assert (reverseInclStack != null);
1797:             if (reverseInclStack.isEmpty()) {
1798:             if (TRACE_PP_STATE_OUT) System.err.println("stack is empty; return default for " + interestedFile);
1799:             return getStartEntryInfo(preprocHandler, state).preprocHandler;
1800:             } else {
1801:             if (TRACE_PP_STATE_OUT) System.err.println("restoring for " + interestedFile);
1802:             // we need to reverse includes stack
1803:             assert (!reverseInclStack.isEmpty()) : "state of stack is " + reverseInclStack;
1804:             StartEntryInfo sei = getStartEntryInfo(preprocHandler, state);
1805:             FileImpl csmFile = sei.csmFile;
1806:             ProjectBase startProject = sei.startProject;
1807:             preprocHandler = sei.preprocHandler;
1808:            
1809:             ProjectBase prevProject = startProject;
1810:             // for testing remember restored file
1811:             long time = REMEMBER_RESTORED ? System.currentTimeMillis() : 0;
1812:             boolean ppStateRestored = false;
1813:             for (int i = 0; i < reverseInclStack.size() && !ppStateRestored; i++) {
1814:             Stack<APTIncludeHandler.IncludeInfo> inclStack = reverse(reverseInclStack);
1815:             if (i > 0) {
1816:             System.err.println("need to try smaller stack");
1817:             sei = getStartEntryInfo(preprocHandler, state);
1818:             preprocHandler = sei.preprocHandler;                        
1819:             for (int j = i; j > 0; j--) {
1820:             inclStack.pop();
1821:             }
1822:             String includedPath = inclStack.peek().getIncludedPath();
1823:             File startFile = new File(includedPath);
1824:             csmFile = null;
1825:             if (prevProject != null) {
1826:             startProject = LibraryManager.getInstance().searchInProjectFiles(prevProject, startFile);
1827:             csmFile = startProject == null ? null : startProject.getFile(startFile);
1828:             }
1829:             if (csmFile == null) {
1830:             CsmFile foundCsmFile = CsmModelAccessor.getModel().findFile(includedPath);
1831:             if (foundCsmFile instanceof FileImpl) {
1832:             csmFile = (FileImpl)foundCsmFile;
1833:             }
1834:             }
1835:             if (csmFile != null) {
1836:             prevProject = csmFile.getProjectImpl();
1837:             }
1838:             }
1839:             APTFile aptLight = null;
1840:             try {
1841:             aptLight = csmFile == null ? null : getAPTLight(csmFile);
1842:             } catch (IOException ex) {
1843:             System.err.println("can't restore preprocessor state for " + interestedFile + //NOI18N
1844:             "\nreason: " + ex.getMessage());//NOI18N
1845:             }
1846:             if (aptLight != null) {
1847:             int stackSize = inclStack.size();
1848:             APTWalker walker = new APTRestorePreprocStateWalker(startProject, aptLight, csmFile, preprocHandler, inclStack, FileContainer.getFileKey(interestedFile, false));
1849:             walker.visit();
1850:             if (preprocHandler.isValid()) {
1851:             if (REMEMBER_RESTORED) {
1852:             if (testRestoredFiles == null) {
1853:             testRestoredFiles = new ArrayList<String>();
1854:             }
1855:             FileImpl interestedFileImpl = getFile(interestedFile);
1856:             assert interestedFileImpl != null;
1857:             String msg = interestedFile.getAbsolutePath() + " [" + (interestedFileImpl.isHeaderFile() ? "H" : interestedFileImpl.isSourceFile() ? "S" : "U") + "]"; // NOI18N
1858:             time = System.currentTimeMillis() - time;
1859:             msg = msg + " within " + time + "ms" + " stack " + stackSize + " elems" + " orininal size was " + reverseInclStack.size(); // NOI18N
1860:             System.err.println("#" + testRestoredFiles.size() + " restored: " + msg); // NOI18N
1861:             testRestoredFiles.add(msg);
1862:             }
1863:             if (TRACE_PP_STATE_OUT) {
1864:             System.err.println("after restoring " + preprocHandler); // NOI18N
1865:             }
1866:             ppStateRestored = true;
1867:             }
1868:             }
1869:             } 
1870:             if (!ppStateRestored) {
1871:             // need to recover from the problem, when start file is invalid or absent
1872:             // try to find project who can create default handler with correct
1873:             // compiler settings
1874:             // preferences is start project
1875:             if (startProject == null) {
1876:             // otherwise use the project owner
1877:             startProject = this;
1878:             }
1879:             preprocHandler = startProject.createDefaultPreprocHandler(interestedFile);
1880:             // remember
1881:             // TODO: file container should accept all without checks
1882:             // otherwise state will not be replaced
1883:             //                synchronized (getFileContainer().getLock(interestedFile)) {
1884:             //                    if (state.equals(getPreprocState(interestedFile))) {
1885:             //                        APTPreprocHandler.State recoveredState = preprocHandler.getState();
1886:             //                        assert !recoveredState.isCompileContext();
1887:             //                        putPreprocState(interestedFile, recoveredState);
1888:             //                    }
1889:             //                }
1890:             }
1891:             return preprocHandler;
1892:             }
1893:             }  
1894:             */
1895:
1896:            private NativeProject findNativeProjectHolder(
1897:                    Set<ProjectBase> visited) {
1898:                visited.add(this );
1899:                NativeProject nativeProject = ModelSupport
1900:                        .getNativeProject(getPlatformProject());
1901:                if (nativeProject == null) {
1902:                    // try to find dependent projects and ask them
1903:                    List<ProjectBase> deps = this .getDependentProjects();
1904:                    for (ProjectBase dependentPrj : deps) {
1905:                        if (!visited.contains(dependentPrj)) {
1906:                            nativeProject = dependentPrj
1907:                                    .findNativeProjectHolder(visited);
1908:                            if (nativeProject != null) {
1909:                                // found 
1910:                                break;
1911:                            }
1912:                        }
1913:                    }
1914:                }
1915:                return nativeProject;
1916:            }
1917:
1918:            private APTPreprocHandler createDefaultPreprocHandler(
1919:                    File interestedFile) {
1920:                NativeProject nativeProject = findNativeProjectHolder(new HashSet(
1921:                        10));
1922:                APTPreprocHandler out = null;
1923:                if (nativeProject != null) {
1924:                    // we have own native project to get settings from
1925:                    NativeFileItem item = new DefaultFileItem(nativeProject,
1926:                            interestedFile.getAbsolutePath());
1927:                    out = createPreprocHandler(item);
1928:                } else {
1929:                    out = createEmptyPreprocHandler(interestedFile);
1930:                }
1931:                assert out != null : "failed creating default ppState for "
1932:                        + interestedFile;
1933:                return out;
1934:            }
1935:
1936:            private static <T> Stack<T> reverse(List<T> original) {
1937:                Stack<T> reverse = new Stack<T>();
1938:                for (int i = original.size() - 1; i >= 0; i--) {
1939:                    T inclInfo = original.get(i);
1940:                    reverse.push(inclInfo);
1941:                }
1942:                return reverse;
1943:            }
1944:
1945:            public static NativeFileItem getCompiledFileItem(FileImpl fileImpl) {
1946:                NativeFileItem out = null;
1947:                ProjectBase filePrj = fileImpl.getProjectImpl();
1948:                if (filePrj != null) {
1949:                    APTPreprocHandler.State state = filePrj
1950:                            .getPreprocState(fileImpl);
1951:                    FileImpl startFile = getStartFile(state);
1952:                    out = startFile != null ? startFile.getNativeFileItem()
1953:                            : null;
1954:                }
1955:                return out;
1956:            }
1957:
1958:            public static FileImpl getStartFile(
1959:                    final APTPreprocHandler.State state) {
1960:                StartEntry startEntry = APTHandlersSupport
1961:                        .extractStartEntry(state);
1962:                ProjectBase startProject = getStartProject(startEntry);
1963:                FileImpl csmFile = startProject == null ? null : startProject
1964:                        .getFile(new File(startEntry.getStartFile()));
1965:                return csmFile;
1966:            }
1967:
1968:            public static ProjectBase getStartProject(
1969:                    final APTPreprocHandler.State state) {
1970:                return getStartProject(APTHandlersSupport
1971:                        .extractStartEntry(state));
1972:            }
1973:
1974:            public static ProjectBase getStartProject(StartEntry startEntry) {
1975:                Key key = startEntry.getStartFileProject();
1976:                ProjectBase prj = (ProjectBase) RepositoryUtils.get(key);
1977:                return prj;
1978:            }
1979:
1980:            public APTFile getAPTLight(CsmFile csmFile) throws IOException {
1981:                APTFile aptLight = null;
1982:                if (TraceFlags.USE_AST_CACHE) {
1983:                    aptLight = CacheManager.getInstance().findAPTLight(csmFile);
1984:                } else {
1985:                    aptLight = APTDriver.getInstance().findAPTLight(
1986:                            ((FileImpl) csmFile).getBuffer());
1987:                }
1988:                return aptLight;
1989:            }
1990:
1991:            public GraphContainer getGraph() {
1992:                return getGraphStorage();
1993:            }
1994:
1995:            protected final static class DefaultFileItem implements 
1996:                    NativeFileItem {
1997:
1998:                private NativeProject project;
1999:                private String absolutePath;
2000:
2001:                public DefaultFileItem(NativeProject project,
2002:                        String absolutePath) {
2003:                    this .project = project;
2004:                    this .absolutePath = absolutePath;
2005:                }
2006:
2007:                public DefaultFileItem(NativeFileItem nativeFile) {
2008:                    this .project = nativeFile.getNativeProject();
2009:                    this .absolutePath = nativeFile.getFile().getAbsolutePath();
2010:                }
2011:
2012:                public static NativeFileItem toDefault(NativeFileItem nativeFile) {
2013:                    // if not already fake
2014:                    if (!(nativeFile instanceof  DefaultFileItem)) {
2015:                        nativeFile = new DefaultFileItem(nativeFile);
2016:                    }
2017:                    return nativeFile;
2018:                }
2019:
2020:                public List<String> getUserMacroDefinitions() {
2021:                    if (project != null) {
2022:                        return project.getUserMacroDefinitions();
2023:                    }
2024:                    return Collections.<String> emptyList();
2025:                }
2026:
2027:                public List<String> getUserIncludePaths() {
2028:                    if (project != null) {
2029:                        return project.getUserIncludePaths();
2030:                    }
2031:                    return Collections.<String> emptyList();
2032:                }
2033:
2034:                public List<String> getSystemMacroDefinitions() {
2035:                    if (project != null) {
2036:                        return project.getSystemMacroDefinitions();
2037:                    }
2038:                    return Collections.<String> emptyList();
2039:                }
2040:
2041:                public List<String> getSystemIncludePaths() {
2042:                    if (project != null) {
2043:                        return project.getSystemIncludePaths();
2044:                    }
2045:                    return Collections.<String> emptyList();
2046:                }
2047:
2048:                public NativeProject getNativeProject() {
2049:                    return project;
2050:                }
2051:
2052:                public File getFile() {
2053:                    return new File(absolutePath);
2054:                }
2055:
2056:                public Language getLanguage() {
2057:                    return NativeFileItem.Language.C_HEADER;
2058:                }
2059:
2060:                public LanguageFlavor getLanguageFlavor() {
2061:                    return NativeFileItem.LanguageFlavor.GENERIC;
2062:                }
2063:
2064:                public boolean isExcluded() {
2065:                    return false;
2066:                }
2067:            }
2068:
2069:            /**
2070:             * Represent the project status.
2071:             *
2072:             * Concerns only initial stage of project lifecycle:
2073:             * allows to distingwish just newly-created project,
2074:             * the phase when files are being added to project (and to parser queue)
2075:             * and the phase when all files are already added.
2076:             *
2077:             * It isn't worth tracking further stages (stable/unstable)
2078:             * since it's error prone (it's better to ask, say, parser queue
2079:             * whether it contains files that belong to this projec or not)
2080:             */
2081:            protected static enum Status {
2082:                Initial, Restored, AddingFiles, Validating, Ready;
2083:            }
2084:
2085:            private transient Status status;
2086:
2087:            /** The task that is run in a request processor during project initialization */
2088:            private Cancellable initializationTask;
2089:
2090:            /** The lock under which the initializationTask is set */
2091:            private Object initializationTaskLock = new Object();
2092:
2093:            private Object waitParseLock = new Object();
2094:
2095:            private ModelImpl model;
2096:            private Unresolved unresolved;
2097:            private CharSequence name;
2098:
2099:            private final CsmUID<CsmNamespace> globalNamespaceUID;
2100:
2101:            private Object platformProject;
2102:
2103:            /**
2104:             * Some notes concerning disposing and disposeLock fields. 
2105:             * 
2106:             * The purpose is not to perform some actions 
2107:             * (such as adding new files, continuing initialization, etc)
2108:             * when the project is going to be disposed.
2109:             * 
2110:             * The disposing field is changed only once, 
2111:             * from false to true (in setDispose() method)
2112:             * 
2113:             * When it is changed to true, no lock is aquired, BUT:
2114:             * it is guaranteed that events take place in the following order:
2115:             * 1) disposing is set to true
2116:             * 2) the disposeLock.writeLock() is locked after that
2117:             * and remains locked during the entire project closure.
2118:             * 
2119:             * Clients who need to check this, are obliged to
2120:             * act in the following sequence:
2121:             * 1) require disposeLock.readLock() 
2122:             * 2) check that the disposing field is still false
2123:             * 3) keep disposeLock.readLock() locked
2124:             * while performing critical actions
2125:             * (the actions that should not be done 
2126:             * when the project is being disposed)
2127:             * 
2128:             */
2129:            private boolean disposing;
2130:            private ReadWriteLock disposeLock = new ReentrantReadWriteLock();
2131:
2132:            private CharSequence uniqueName = null; // lazy initialized
2133:
2134:            private Map<CharSequence, CsmUID<CsmNamespace>> namespaces = new ConcurrentHashMap<CharSequence, CsmUID<CsmNamespace>>();
2135:
2136:            private ClassifierContainer classifierContainer = new ClassifierContainer();
2137:
2138:            // collection of sharable system macros and system includes
2139:            private APTSystemStorage sysAPTData = APTSystemStorage.getDefault();
2140:
2141:            private Object namespaceLock = new String(
2142:                    "namespaceLock in Projectbase " + hashCode()); // NOI18N
2143:
2144:            private Key declarationsSorageKey;
2145:            private Key fileContainerKey;
2146:            private Key graphStorageKey;
2147:
2148:            protected final SourceRootContainer projectRoots = new SourceRootContainer();
2149:
2150:            //private NamespaceImpl fakeNamespace;
2151:
2152:            // test variables.
2153:            private static final boolean TRACE_PP_STATE_OUT = DebugUtils
2154:                    .getBoolean("cnd.dump.preproc.state", false);
2155:            private static final boolean REMEMBER_RESTORED = TraceFlags.CLEAN_MACROS_AFTER_PARSE
2156:                    && (DebugUtils.getBoolean("cnd.remember.restored", false) || TRACE_PP_STATE_OUT);
2157:            public static final int GATHERING_MACROS = 0;
2158:            public static final int GATHERING_TOKENS = 1;
2159:
2160:            ////////////////////////////////////////////////////////////////////////////
2161:            /**
2162:             * for tests only
2163:             */
2164:            public static List testGetRestoredFiles() {
2165:                return testRestoredFiles;
2166:            }
2167:
2168:            private static List<String> testRestoredFiles = null;
2169:
2170:            ////////////////////////////////////////////////////////////////////////////
2171:
2172:            ////////////////////////////////////////////////////////////////////////////
2173:            // impl of persistent
2174:
2175:            public void write(DataOutput aStream) throws IOException {
2176:                assert aStream != null;
2177:                UIDObjectFactory aFactory = UIDObjectFactory
2178:                        .getDefaultFactory();
2179:                assert aFactory != null;
2180:                assert this .name != null;
2181:                aStream.writeUTF(this .name.toString());
2182:                aStream.writeUTF(RepositoryUtils.getUnitName(getUID())
2183:                        .toString());
2184:                aFactory.writeUID(this .globalNamespaceUID, aStream);
2185:                aFactory.writeStringToUIDMap(this .namespaces, aStream, false);
2186:                classifierContainer.write(aStream);
2187:
2188:                ProjectComponent.writeKey(fileContainerKey, aStream);
2189:                ProjectComponent.writeKey(declarationsSorageKey, aStream);
2190:                ProjectComponent.writeKey(graphStorageKey, aStream);
2191:
2192:                PersistentUtils.writeUTF(this .uniqueName, aStream);
2193:            }
2194:
2195:            protected ProjectBase(DataInput aStream) throws IOException {
2196:
2197:                setStatus(Status.Restored);
2198:
2199:                assert aStream != null;
2200:                UIDObjectFactory aFactory = UIDObjectFactory
2201:                        .getDefaultFactory();
2202:                assert aFactory != null : "default UID factory can not be bull";
2203:
2204:                this .name = ProjectNameCache.getManager().getString(
2205:                        aStream.readUTF());
2206:                assert this .name != null : "project name can not be null";
2207:
2208:                String unitName = aStream.readUTF();
2209:
2210:                this .globalNamespaceUID = aFactory.readUID(aStream);
2211:                assert globalNamespaceUID != null : "globalNamespaceUID can not be null";
2212:
2213:                aFactory.readStringToUIDMap(this .namespaces, aStream,
2214:                        QualifiedNameCache.getManager());
2215:                this .classifierContainer = new ClassifierContainer(aStream);
2216:
2217:                fileContainerKey = ProjectComponent.readKey(aStream);
2218:                assert fileContainerKey != null : "fileContainerKey can not be null";
2219:
2220:                declarationsSorageKey = ProjectComponent.readKey(aStream);
2221:                assert declarationsSorageKey != null : "declarationsSorageKey can not be null";
2222:
2223:                graphStorageKey = ProjectComponent.readKey(aStream);
2224:                assert graphStorageKey != null : "graphStorageKey can not be null";
2225:
2226:                this .uniqueName = PersistentUtils.readUTF(aStream);
2227:                assert uniqueName != null : "uniqueName can not be null";
2228:                this .uniqueName = ProjectNameCache.getManager().getString(
2229:                        this .uniqueName);
2230:
2231:                this .model = (ModelImpl) CsmModelAccessor.getModel();
2232:            }
2233:
2234:            DeclarationContainer getDeclarationsSorage() {
2235:                return (DeclarationContainer) RepositoryUtils
2236:                        .get(declarationsSorageKey);
2237:            }
2238:
2239:            FileContainer getFileContainer() {
2240:                FileContainer fc = (FileContainer) RepositoryUtils
2241:                        .get(fileContainerKey);
2242:                assert fc != null : "Failed to get FileContainer by key "
2243:                        + fileContainerKey;
2244:                return fc;
2245:            }
2246:
2247:            public GraphContainer getGraphStorage() {
2248:                GraphContainer gc = (GraphContainer) RepositoryUtils
2249:                        .get(graphStorageKey);
2250:                assert gc != null : "Failed to get GraphContainer by key "
2251:                        + graphStorageKey;
2252:                return gc;
2253:            }
2254:        }
w__ww_.__j__a___va__2_s__.___c___o___m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.