Source Code Cross Referenced for RepositoryUpdater.java in  » IDE-Netbeans » gsf » org » netbeans » modules » gsfret » source » usages » 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 » gsf » org.netbeans.modules.gsfret.source.usages 
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-2006 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.gsfret.source.usages;
0043:
0044:        import java.beans.PropertyChangeEvent;
0045:        import java.beans.PropertyChangeListener;
0046:        import java.io.File;
0047:        import java.io.IOException;
0048:        import java.lang.ref.Reference;
0049:        import java.lang.ref.WeakReference;
0050:        import java.net.URI;
0051:        import java.net.URL;
0052:        import java.text.ParseException;
0053:        import java.util.ArrayList;
0054:        import java.util.Collections;
0055:        import java.util.HashMap;
0056:        import java.util.HashSet;
0057:        import java.util.Iterator;
0058:        import java.util.LinkedList;
0059:        import java.util.List;
0060:        import java.util.Map;
0061:        import java.util.RandomAccess;
0062:        import java.util.Set;
0063:        import java.util.Stack;
0064:        import java.util.StringTokenizer;
0065:        import java.util.Timer;
0066:        import java.util.TimerTask;
0067:        import java.util.TooManyListenersException;
0068:        import java.util.WeakHashMap;
0069:        import java.util.concurrent.CountDownLatch;
0070:        import java.util.concurrent.atomic.AtomicBoolean;
0071:        import java.util.logging.Level;
0072:        import java.util.logging.Logger;
0073:        import javax.swing.event.ChangeEvent;
0074:        import javax.swing.event.ChangeListener;
0075:        import org.apache.lucene.document.DateTools;
0076:        import org.netbeans.modules.gsf.api.Error;
0077:        import org.netbeans.modules.gsf.api.Severity;
0078:        import org.netbeans.modules.gsf.api.Indexer;
0079:        import org.netbeans.modules.gsf.api.ParseEvent;
0080:        import org.netbeans.modules.gsf.api.ParseListener;
0081:        import org.netbeans.modules.gsf.api.ParserFile;
0082:        import org.netbeans.modules.gsf.api.ParserResult;
0083:        import org.netbeans.modules.gsf.api.CancellableTask;
0084:        import org.netbeans.modules.gsfpath.api.classpath.ClassPath;
0085:        import org.netbeans.modules.gsfpath.api.queries.SourceLevelQuery;
0086:        import org.netbeans.api.progress.ProgressHandle;
0087:        import org.netbeans.api.progress.ProgressHandleFactory;
0088:        import org.netbeans.api.queries.VisibilityQuery;
0089:        import org.netbeans.modules.gsf.GsfTaskProvider;
0090:        import org.netbeans.napi.gsfret.source.ClasspathInfo;
0091:        import org.netbeans.napi.gsfret.source.CompilationInfo;
0092:        import org.netbeans.napi.gsfret.source.ParserTaskImpl;
0093:        import org.netbeans.napi.gsfret.source.Source;
0094:        import org.netbeans.modules.gsf.Language;
0095:        import org.netbeans.modules.gsf.LanguageRegistry;
0096:        import org.netbeans.modules.gsfret.source.GlobalSourcePath;
0097:        import org.netbeans.modules.gsfret.source.SourceAccessor;
0098:        import org.netbeans.modules.gsfret.source.parsing.FileObjects;
0099:        import org.netbeans.modules.gsfret.source.util.LowMemoryEvent;
0100:        import org.netbeans.modules.gsfret.source.util.LowMemoryListener;
0101:        import org.netbeans.modules.gsfret.source.util.LowMemoryNotifier;
0102:        import org.netbeans.modules.gsfpath.spi.classpath.ClassPathFactory;
0103:        import org.netbeans.modules.gsfpath.spi.classpath.support.ClassPathSupport;
0104:        import org.openide.filesystems.FileAttributeEvent;
0105:        import org.openide.filesystems.FileChangeListener;
0106:        import org.openide.filesystems.FileEvent;
0107:        import org.openide.filesystems.FileObject;
0108:        import org.openide.filesystems.FileRenameEvent;
0109:        import org.openide.filesystems.FileStateInvalidException;
0110:        import org.openide.filesystems.FileSystem;
0111:        import org.openide.filesystems.FileUtil;
0112:        import org.openide.filesystems.URLMapper;
0113:        import org.openide.util.Exceptions;
0114:        import org.openide.util.NbBundle;
0115:        import org.openide.util.TopologicalSortException;
0116:        import org.openide.util.Utilities;
0117:
0118:        /**
0119:         * RepositoryUpdater is in charge of maintaining indices of the various classes in 
0120:         * the system, for use by code completion, go to declaration, etc.  The classes include
0121:         * not only the user's source and test directories, but jars from the boot class path etc.
0122:         * The RepositoryUpdater schedules indexing jobs, watches filesystems for modifications,
0123:         * determines whether an index is out of date, etc.
0124:         * 
0125:         * This class is originally from Retouche, under the java/source module. Since it's
0126:         * an important and fairly complicated piece of logic, I am trying my best to keep
0127:         * my copy in sync with the java one. Therefore, I have left the original formatting
0128:         * in place as much as possible. Please don't make gratuitous formatting changes that
0129:         * makes diffing harder.
0130:         * 
0131:         * There are some important changes. Obviously, the various javac-specific setup code
0132:         * has changed, and I also need to -iterate- over files to be indexed to let the
0133:         * potentially multiple language indexers each have a chance to index the file.
0134:         * I have also changed references to other parts that have been renamed, such
0135:         * as JavaSource => Source, etc.
0136:         * 
0137:         * @author Tomas Zezula
0138:         * @author Tor Norbye
0139:         */
0140:        public class RepositoryUpdater implements  PropertyChangeListener,
0141:                FileChangeListener {
0142:            // Flag for controlling last-minute workaround for issue #120231
0143:            //    private static final boolean CLOSE_INDICES = Boolean.getBoolean("gsf.closeindices");
0144:
0145:            private static final boolean PREINDEXING = Boolean
0146:                    .getBoolean("gsf.preindexing");
0147:
0148:            private static final Logger LOGGER = Logger
0149:                    .getLogger(RepositoryUpdater.class.getName());
0150:            private static final Set<String> ignoredDirectories = parseSet(
0151:                    "org.netbeans.javacore.ignoreDirectories", "SCCS CVS .svn"); // NOI18N
0152:            private static final boolean noscan = Boolean
0153:                    .getBoolean("netbeans.javacore.noscan"); //NOI18N
0154:            private static final boolean PERF_TEST = Boolean
0155:                    .getBoolean("perf.refactoring.test");
0156:            //private static final String PACKAGE_INFO = "package-info.java";  //NOI18N
0157:
0158:            private static final int DELAY = Utilities.isWindows() ? 2000
0159:                    : 1000;
0160:
0161:            private static RepositoryUpdater instance;
0162:
0163:            private final GlobalSourcePath cpImpl;
0164:            private final ClassPath cp;
0165:            private final ClassPath ucp;
0166:            private final ClassPath binCp;
0167:            private Set<URL> scannedRoots;
0168:            private Set<URL> scannedBinaries;
0169:            private Map<URL, List<URL>> deps; //todo: may be shared with scannedRoots, may save some HashMap.Entry
0170:            private Delay delay;
0171:            private Work currentWork;
0172:            private boolean dirty;
0173:            private int noSubmited;
0174:
0175:            //Preprocessor support
0176:            //private final Map<URL, JavaFileFilterImplementation> filters = Collections.synchronizedMap(new HashMap<URL, JavaFileFilterImplementation>());
0177:            private final FilterListener filterListener = new FilterListener();
0178:
0179:            /** Creates a new instance of RepositoryUpdater */
0180:            private RepositoryUpdater() {
0181:                try {
0182:                    this .scannedRoots = Collections
0183:                            .synchronizedSet(new HashSet<URL>());
0184:                    this .scannedBinaries = Collections
0185:                            .synchronizedSet(new HashSet<URL>());
0186:                    this .deps = Collections
0187:                            .synchronizedMap(new HashMap<URL, List<URL>>());
0188:                    this .delay = new Delay();
0189:                    this .cpImpl = GlobalSourcePath.getDefault();
0190:                    this .cpImpl.setExcludesListener(this );
0191:                    this .cp = ClassPathFactory.createClassPath(this .cpImpl
0192:                            .getSourcePath());
0193:                    this .cp.addPropertyChangeListener(this );
0194:                    this .ucp = ClassPathFactory.createClassPath(this .cpImpl
0195:                            .getUnknownSourcePath());
0196:                    this .binCp = ClassPathFactory.createClassPath(this .cpImpl
0197:                            .getBinaryPath());
0198:                    this .registerFileSystemListener();
0199:                    submitBatch();
0200:                } catch (TooManyListenersException e) {
0201:                    throw new IllegalStateException();
0202:                }
0203:            }
0204:
0205:            public ClassPath getScannedSources() {
0206:                return this .cp;
0207:            }
0208:
0209:            public ClassPath getScannedBinaries() {
0210:                return this .binCp;
0211:            }
0212:
0213:            public Map<URL, List<URL>> getDependencies() {
0214:                return new HashMap<URL, List<URL>>(this .deps);
0215:            }
0216:
0217:            public void close() {
0218:                this .cp.removePropertyChangeListener(this );
0219:                this .unregisterFileSystemListener();
0220:                this .delay.cancel();
0221:            }
0222:
0223:            public void propertyChange(PropertyChangeEvent evt) {
0224:                if (ClassPath.PROP_ROOTS.equals(evt.getPropertyName())) {
0225:                    submitBatch();
0226:                } else if (GlobalSourcePath.PROP_INCLUDES.equals(evt
0227:                        .getPropertyName())) {
0228:                    ClassPath changedCp = (ClassPath) evt.getNewValue();
0229:                    assert changedCp != null;
0230:                    for (ClassPath.Entry e : changedCp.entries()) {
0231:                        URL root = e.getURL();
0232:                        scheduleCompilation(root, root, true);
0233:                    }
0234:                }
0235:            }
0236:
0237:            private synchronized void submitBatch() {
0238:                if (this .currentWork == null) {
0239:                    this .currentWork = Work.batch();
0240:                    submit(this .currentWork);
0241:                } else {
0242:                    this .dirty = true;
0243:                }
0244:            }
0245:
0246:            public synchronized boolean isScanInProgress() {
0247:                return this .noSubmited > 0;
0248:            }
0249:
0250:            public synchronized void waitScanFinished()
0251:                    throws InterruptedException {
0252:                while (this .noSubmited > 0) {
0253:                    this .wait();
0254:                }
0255:            }
0256:
0257:            private synchronized boolean isDirty() {
0258:                if (this .dirty) {
0259:                    this .dirty = false;
0260:                    return true;
0261:                } else {
0262:                    this .currentWork = null;
0263:                    return false;
0264:                }
0265:            }
0266:
0267:            private synchronized void resetDirty() {
0268:                this .dirty = false;
0269:                this .currentWork = null;
0270:            }
0271:
0272:            public void fileRenamed(FileRenameEvent fe) {
0273:                final FileObject fo = fe.getFile();
0274:                try {
0275:                    if ((isRelevantSource(fo) || fo.isFolder())
0276:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0277:                        final URL root = getOwningSourceRoot(fo);
0278:                        if (root != null) {
0279:                            String originalName = fe.getName();
0280:                            final String originalExt = fe.getExt();
0281:                            if (originalExt.length() > 0) {
0282:                                originalName = originalName + '.' + originalExt; //NOI18N
0283:                            }
0284:                            final File parentFile = FileUtil.toFile(fo
0285:                                    .getParent());
0286:                            if (parentFile != null) {
0287:                                final URL original = new File(parentFile,
0288:                                        originalName).toURI().toURL();
0289:                                submit(Work.delete(original, root, fo
0290:                                        .isFolder()));
0291:                                delay.post(Work.compile(fo, root));
0292:                            }
0293:                        }
0294:                    } else if (isBinary(fo)
0295:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0296:                        final URL root = getOwningBinaryRoot(fo);
0297:                        if (root != null) {
0298:                            String originalName = fe.getName();
0299:                            final String originalExt = fe.getExt();
0300:                            if (originalExt.length() > 0) {
0301:                                originalName = originalName + '.' + originalExt; //NOI18N
0302:                            }
0303:                            final File parentFile = FileUtil.toFile(fo
0304:                                    .getParent());
0305:                            if (parentFile != null) {
0306:                                final URL original = new File(parentFile,
0307:                                        originalName).toURI().toURL();
0308:                                submit(Work.binary(original, root, fo
0309:                                        .isFolder()));
0310:                                submit(Work.binary(fo, root));
0311:                            }
0312:                        }
0313:                    }
0314:                } catch (IOException ioe) {
0315:                    Exceptions.printStackTrace(ioe);
0316:                }
0317:            }
0318:
0319:            public void fileAttributeChanged(FileAttributeEvent fe) {
0320:                //Not interesting, do nothing
0321:            }
0322:
0323:            public void fileFolderCreated(FileEvent fe) {
0324:                //In ideal case this should do nothing,
0325:                //but in Netbeans newly created folder may
0326:                //already contain files
0327:                final FileObject fo = fe.getFile();
0328:                try {
0329:                    final URL root = getOwningSourceRoot(fo);
0330:                    if (root != null
0331:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0332:                        scheduleCompilation(fo, root);
0333:                    }
0334:                } catch (IOException ioe) {
0335:                    Exceptions.printStackTrace(ioe);
0336:                }
0337:            }
0338:
0339:            public void fileDeleted(FileEvent fe) {
0340:                final FileObject fo = fe.getFile();
0341:                final boolean isFolder = fo.isFolder();
0342:                try {
0343:                    boolean relevantSource = isRelevantSource(fo);
0344:                    if (!relevantSource
0345:                            && "content/unknown".equals(fo.getMIMEType())) { // NOI18N
0346:                        // When deleted, file objects lose their mimetypes...
0347:                        relevantSource = true;
0348:                    }
0349:                    if ((relevantSource || isFolder)
0350:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0351:                        final URL root = getOwningSourceRoot(fo);
0352:                        if (root != null) {
0353:                            submit(Work.delete(fo, root, isFolder));
0354:                        }
0355:                    } else if ((isBinary(fo) || isFolder)
0356:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0357:                        final URL root = getOwningBinaryRoot(fo);
0358:                        if (root != null) {
0359:                            submit(Work.binary(fo, root));
0360:                        }
0361:                    }
0362:                } catch (IOException ioe) {
0363:                    Exceptions.printStackTrace(ioe);
0364:                }
0365:            }
0366:
0367:            public void fileDataCreated(FileEvent fe) {
0368:                final FileObject fo = fe.getFile();
0369:                try {
0370:                    if (isRelevantSource(fo)
0371:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0372:                        final URL root = getOwningSourceRoot(fo);
0373:                        if (root != null) {
0374:                            postCompilation(fo, root);
0375:                        }
0376:                    } else if (isBinary(fo)
0377:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0378:                        final URL root = getOwningBinaryRoot(fo);
0379:                        if (root != null) {
0380:                            submit(Work.binary(fo, root));
0381:                        }
0382:                    }
0383:                } catch (IOException ioe) {
0384:                    Exceptions.printStackTrace(ioe);
0385:                }
0386:            }
0387:
0388:            public void fileChanged(FileEvent fe) {
0389:                final FileObject fo = fe.getFile();
0390:                try {
0391:                    if (isRelevantSource(fo)
0392:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0393:                        final URL root = getOwningSourceRoot(fo);
0394:                        if (root != null) {
0395:                            postCompilation(fo, root);
0396:                        }
0397:                    } else if (isBinary(fo)
0398:                            && VisibilityQuery.getDefault().isVisible(fo)) {
0399:                        final URL root = getOwningBinaryRoot(fo);
0400:                        if (root != null) {
0401:                            submit(Work.binary(fo, root));
0402:                        }
0403:                    }
0404:                } catch (IOException ioe) {
0405:                    Exceptions.printStackTrace(ioe);
0406:                }
0407:            }
0408:
0409:            public final void scheduleCompilation(final FileObject fo,
0410:                    final FileObject root) throws IOException {
0411:                URL foURL = fo.getURL();
0412:                URL rootURL = root.getURL();
0413:                assert "file".equals(foURL.getProtocol())
0414:                        && "file".equals(rootURL.getProtocol());
0415:                scheduleCompilation(foURL, rootURL, fo.isFolder());
0416:            }
0417:
0418:            private final void scheduleCompilation(final FileObject fo,
0419:                    final URL root) throws IOException {
0420:                scheduleCompilation(fo.getURL(), root, fo.isFolder());
0421:            }
0422:
0423:            private final void scheduleCompilation(final URL file,
0424:                    final URL root, boolean isFolder) {
0425:                submit(Work.compile(file, root, isFolder));
0426:            }
0427:
0428:            private final void postCompilation(final FileObject file,
0429:                    final URL root) throws FileStateInvalidException {
0430:                delay.post(Work.compile(file, root));
0431:            }
0432:
0433:            /**
0434:             * This method is only for unit tests.
0435:             * Test can schedule compilation and wait on the returned {@link CountDownLatch}
0436:             * until the compilation is finished.
0437:             * @param folder to be compiled
0438:             * @param root the source root. The folder has to be either under the root or
0439:             * equal to the root.
0440:             * @return {@link CountDownLatch} to wait on.
0441:             */
0442:            public final CountDownLatch scheduleCompilationAndWait(
0443:                    final FileObject folder, final FileObject root)
0444:                    throws IOException {
0445:                CountDownLatch[] latch = new CountDownLatch[1];
0446:                submit(Work.compile(folder, root.getURL(), latch));
0447:                return latch[0];
0448:            }
0449:
0450:            private void submit(final Work work) {
0451:                if (!noscan) {
0452:                    synchronized (this ) {
0453:                        this .noSubmited++;
0454:                    }
0455:                    final CompileWorker cw = new CompileWorker(work);
0456:                    SourceAccessor.getINSTANCE().runSpecialTask(cw,
0457:                            Source.Priority.MAX);
0458:                }
0459:            }
0460:
0461:            private void registerFileSystemListener() {
0462:                FileUtil.addFileChangeListener(this );
0463:            }
0464:
0465:            private void unregisterFileSystemListener() {
0466:                FileUtil.removeFileChangeListener(this );
0467:            }
0468:
0469:            private URL getOwningSourceRoot(final FileObject fo) {
0470:                if (fo == null) {
0471:                    return null;
0472:                }
0473:                List<URL> clone = new ArrayList(this .scannedRoots);
0474:                for (URL root : clone) {
0475:                    FileObject rootFo = URLMapper.findFileObject(root);
0476:                    if (rootFo != null && FileUtil.isParentOf(rootFo, fo)) {
0477:                        return root;
0478:                    }
0479:                }
0480:                return null;
0481:            }
0482:
0483:            private URL getOwningBinaryRoot(final FileObject fo) {
0484:                if (fo == null) {
0485:                    return null;
0486:                }
0487:                try {
0488:                    synchronized (this .scannedBinaries) {
0489:                        URL foURL = fo.getURL();
0490:                        for (URL root : this .scannedBinaries) {
0491:                            URL fileURL = FileUtil.getArchiveFile(root);
0492:                            boolean archive = true;
0493:                            if (fileURL == null) {
0494:                                fileURL = root;
0495:                                archive = false;
0496:                            }
0497:                            String filePath = fileURL.getPath();
0498:                            String foPath = foURL.getPath();
0499:                            if (filePath.equals(foPath)) {
0500:                                return root;
0501:                            }
0502:                            if (!archive && foPath.startsWith(filePath)) {
0503:                                return root;
0504:                            }
0505:                        }
0506:                    }
0507:                } catch (FileStateInvalidException fsi) {
0508:                    Exceptions.printStackTrace(fsi);
0509:                }
0510:                return null;
0511:            }
0512:
0513:            /**
0514:             * Temporary implementation which does not care about
0515:             * extended mime types like text/x-something+x-java
0516:             */
0517:            public static boolean isRelevantSource(final FileObject fo) {
0518:                if (fo.isFolder()) {
0519:                    return false;
0520:                }
0521:
0522:                if (LanguageRegistry.getInstance()
0523:                        .isSupported(fo.getMIMEType())) {
0524:                    return true;
0525:                }
0526:
0527:                return false;
0528:            }
0529:
0530:            private static boolean isBinary(final FileObject fo) {
0531:                return false;
0532:                /* XXX TODO no support for binary persistence files yet, such as compiled ruby files etc.
0533:                if (fo.isFolder()) {
0534:                    return false;
0535:                }
0536:                String ext = fo.getExt().toLowerCase();
0537:                if (FileObjects.CLASS.equals(ext) ||
0538:                    FileObjects.JAR.equals(ext) ||
0539:                    FileObjects.ZIP.equals(ext)) { 
0540:                        return true;
0541:                }        
0542:                return false;
0543:                 */
0544:            }
0545:
0546:            private static enum WorkType {
0547:                COMPILE_BATCH, COMPILE_CONT, COMPILE, DELETE, UPDATE_BINARY, FILTER_CHANGED
0548:            };
0549:
0550:            private static class Work {
0551:                private final WorkType workType;
0552:                private final CountDownLatch latch;
0553:
0554:                protected Work(WorkType workType, CountDownLatch latch) {
0555:                    assert workType != null;
0556:                    this .workType = workType;
0557:                    this .latch = latch;
0558:                }
0559:
0560:                public WorkType getType() {
0561:                    return this .workType;
0562:                }
0563:
0564:                public void finished() {
0565:                    if (this .latch != null) {
0566:                        this .latch.countDown();
0567:                    }
0568:                }
0569:
0570:                public static Work batch() {
0571:                    return new Work(WorkType.COMPILE_BATCH, null);
0572:                }
0573:
0574:                public static Work compile(final FileObject file, final URL root)
0575:                        throws FileStateInvalidException {
0576:                    return compile(file.getURL(), root, file.isFolder());
0577:                }
0578:
0579:                public static Work compile(final URL file, final URL root,
0580:                        boolean isFolder) {
0581:                    assert file != null && root != null;
0582:                    return new SingleRootWork(WorkType.COMPILE, file, root,
0583:                            isFolder, null);
0584:                }
0585:
0586:                public static Work compile(final FileObject file,
0587:                        final URL root, CountDownLatch[] latch)
0588:                        throws FileStateInvalidException {
0589:                    assert file != null && root != null;
0590:                    assert latch != null && latch.length == 1
0591:                            && latch[0] == null;
0592:                    latch[0] = new CountDownLatch(1);
0593:                    return new SingleRootWork(WorkType.COMPILE, file.getURL(),
0594:                            root, file.isFolder(), latch[0]);
0595:                }
0596:
0597:                public static Work delete(final FileObject file,
0598:                        final URL root, final boolean isFolder)
0599:                        throws FileStateInvalidException {
0600:                    return delete(file.getURL(), root, file.isFolder());
0601:                }
0602:
0603:                public static Work delete(final URL file, final URL root,
0604:                        final boolean isFolder) {
0605:                    assert file != null && root != null;
0606:                    return new SingleRootWork(WorkType.DELETE, file, root,
0607:                            isFolder, null);
0608:                }
0609:
0610:                public static Work binary(final FileObject file, final URL root)
0611:                        throws FileStateInvalidException {
0612:                    return binary(file.getURL(), root, file.isFolder());
0613:                }
0614:
0615:                public static Work binary(final URL file, final URL root,
0616:                        boolean isFolder) {
0617:                    assert file != null && root != null;
0618:                    return new SingleRootWork(WorkType.UPDATE_BINARY, file,
0619:                            root, isFolder, null);
0620:                }
0621:
0622:                public static Work filterChange(final List<URL> roots) {
0623:                    assert roots != null;
0624:                    return new MultiRootsWork(WorkType.FILTER_CHANGED, roots,
0625:                            null);
0626:                }
0627:
0628:            }
0629:
0630:            private static class SingleRootWork extends Work {
0631:
0632:                private URL file;
0633:                private URL root;
0634:                private boolean isFolder;
0635:
0636:                public SingleRootWork(WorkType type, URL file, URL root,
0637:                        boolean isFolder, CountDownLatch latch) {
0638:                    super (type, latch);
0639:                    this .file = file;
0640:                    this .root = root;
0641:                    this .isFolder = isFolder;
0642:                }
0643:
0644:                public URL getFile() {
0645:                    return this .file;
0646:                }
0647:
0648:                public URL getRoot() {
0649:                    return this .root;
0650:                }
0651:
0652:                public boolean isFolder() {
0653:                    return this .isFolder;
0654:                }
0655:
0656:            }
0657:
0658:            private static class MultiRootsWork extends Work {
0659:                private List<URL> roots;
0660:
0661:                public MultiRootsWork(WorkType type, List<URL> roots,
0662:                        CountDownLatch latch) {
0663:                    super (type, latch);
0664:                    this .roots = roots;
0665:                }
0666:
0667:                public List<URL> getRoots() {
0668:                    return roots;
0669:                }
0670:            }
0671:
0672:            private final class CompileWorker implements 
0673:                    CancellableTask<CompilationInfo> {
0674:
0675:                private Work work;
0676:                private List<URL> state;
0677:                private Set<URL> oldRoots;
0678:                private Set<URL> oldBinaries;
0679:                private Set<URL> newBinaries;
0680:                private ProgressHandle handle;
0681:                private final Set<URI> dirtyCrossFiles;
0682:                private final Set<URL> ignoreExcludes;
0683:                private final AtomicBoolean canceled;
0684:
0685:                public CompileWorker(Work work) {
0686:                    assert work != null;
0687:                    this .work = work;
0688:                    this .canceled = new AtomicBoolean(false);
0689:                    this .dirtyCrossFiles = new HashSet<URI>();
0690:                    this .ignoreExcludes = new HashSet<URL>();
0691:                }
0692:
0693:                public void cancel() {
0694:                    this .canceled.set(true);
0695:                }
0696:
0697:                public void run(final CompilationInfo nullInfo)
0698:                        throws IOException {
0699:                    ClassIndexManager
0700:                            ./*getDefault().*/writeLock(new ClassIndexManager.ExceptionAction<Void>() {
0701:
0702:                                @SuppressWarnings("fallthrough")
0703:                                public Void run() throws IOException {
0704:                                    boolean continuation = false;
0705:                                    try {
0706:                                        final WorkType type = work.getType();
0707:                                        switch (type) {
0708:                                        case FILTER_CHANGED:
0709:                                            try {
0710:                                                final MultiRootsWork mw = (MultiRootsWork) work;
0711:                                                final List<URL> roots = mw
0712:                                                        .getRoots();
0713:                                                final Map<URL, List<URL>> depGraph = new HashMap<URL, List<URL>>();
0714:                                                for (URL root : roots) {
0715:                                                    findDependencies(root,
0716:                                                            new Stack<URL>(),
0717:                                                            depGraph, null,
0718:                                                            false);
0719:                                                }
0720:                                                state = Utilities
0721:                                                        .topologicalSort(roots,
0722:                                                                depGraph);
0723:                                                for (java.util.ListIterator<URL> it = state
0724:                                                        .listIterator(state
0725:                                                                .size()); it
0726:                                                        .hasPrevious();) {
0727:                                                    final URL rootURL = it
0728:                                                            .previous();
0729:                                                    it.remove();
0730:                                                    updateFolder(rootURL,
0731:                                                            rootURL, true,
0732:                                                            handle);
0733:                                                }
0734:                                            } catch (final TopologicalSortException tse) {
0735:                                                final IllegalStateException ise = new IllegalStateException();
0736:                                                throw (IllegalStateException) ise
0737:                                                        .initCause(tse);
0738:                                            }
0739:                                            break;
0740:                                        case COMPILE_BATCH: {
0741:                                            assert handle == null;
0742:                                            handle = ProgressHandleFactory
0743:                                                    .createHandle(NbBundle
0744:                                                            .getMessage(
0745:                                                                    RepositoryUpdater.class,
0746:                                                                    "MSG_BackgroundCompileStart"));
0747:                                            handle.start();
0748:                                            boolean completed = false;
0749:                                            try {
0750:                                                oldRoots = new HashSet<URL>(
0751:                                                        scannedRoots);
0752:                                                oldBinaries = new HashSet<URL>(
0753:                                                        scannedBinaries);
0754:                                                final List<ClassPath.Entry> entries = new LinkedList<ClassPath.Entry>();
0755:                                                entries.addAll(cp.entries());
0756:                                                entries.addAll(ucp.entries());
0757:                                                final List<ClassPath.Entry> binaryEntries = binCp
0758:                                                        .entries();
0759:                                                newBinaries = new HashSet<URL>();
0760:                                                for (ClassPath.Entry entry : binaryEntries) {
0761:                                                    URL binRoot = entry
0762:                                                            .getURL();
0763:                                                    if (!oldBinaries
0764:                                                            .remove(binRoot)) {
0765:                                                        newBinaries
0766:                                                                .add(binRoot);
0767:                                                    }
0768:                                                }
0769:                                                final Map<URL, List<URL>> depGraph = new HashMap<URL, List<URL>>();
0770:                                                for (ClassPath.Entry entry : entries) {
0771:                                                    final URL rootURL = entry
0772:                                                            .getURL();
0773:                                                    findDependencies(rootURL,
0774:                                                            new Stack<URL>(),
0775:                                                            depGraph,
0776:                                                            newBinaries, true);
0777:                                                }
0778:                                                CompileWorker.this .state = Utilities
0779:                                                        .topologicalSort(
0780:                                                                depGraph
0781:                                                                        .keySet(),
0782:                                                                depGraph);
0783:                                                deps.putAll(depGraph);
0784:                                                completed = true;
0785:                                            } catch (final TopologicalSortException tse) {
0786:                                                final IllegalStateException ise = new IllegalStateException();
0787:                                                throw (IllegalStateException) ise
0788:                                                        .initCause(tse);
0789:                                            } finally {
0790:                                                if (!completed) {
0791:                                                    resetDirty();
0792:                                                }
0793:                                            }
0794:                                        }
0795:                                        case COMPILE_CONT:
0796:                                            boolean completed = false;
0797:                                            try {
0798:                                                if (!scanRoots()) {
0799:                                                    CompileWorker.this .work = new Work(
0800:                                                            WorkType.COMPILE_CONT,
0801:                                                            null);
0802:                                                    SourceAccessor
0803:                                                            .getINSTANCE()
0804:                                                            .runSpecialTask(
0805:                                                                    CompileWorker.this ,
0806:                                                                    Source.Priority.MAX);
0807:                                                    continuation = true;
0808:                                                    return null;
0809:                                                }
0810:                                                while (isDirty()) {
0811:                                                    assert CompileWorker.this .state
0812:                                                            .isEmpty();
0813:                                                    final List<ClassPath.Entry> entries = new LinkedList<ClassPath.Entry>();
0814:                                                    entries
0815:                                                            .addAll(cp
0816:                                                                    .entries());
0817:                                                    entries.addAll(ucp
0818:                                                            .entries());
0819:                                                    final List<ClassPath.Entry> binaryEntries = binCp
0820:                                                            .entries();
0821:                                                    newBinaries = new HashSet<URL>();
0822:                                                    for (ClassPath.Entry entry : binaryEntries) {
0823:                                                        URL binRoot = entry
0824:                                                                .getURL();
0825:                                                        if (!scannedBinaries
0826:                                                                .contains(binRoot)) {
0827:                                                            newBinaries
0828:                                                                    .add(binRoot);
0829:                                                        } else {
0830:                                                            oldBinaries
0831:                                                                    .remove(binRoot);
0832:                                                        }
0833:                                                    }
0834:                                                    final Map<URL, List<URL>> depGraph = new HashMap<URL, List<URL>>();
0835:                                                    for (ClassPath.Entry entry : entries) {
0836:                                                        final URL rootURL = entry
0837:                                                                .getURL();
0838:                                                        findDependencies(
0839:                                                                rootURL,
0840:                                                                new Stack<URL>(),
0841:                                                                depGraph,
0842:                                                                newBinaries,
0843:                                                                true);
0844:                                                    }
0845:                                                    try {
0846:                                                        CompileWorker.this .state = Utilities
0847:                                                                .topologicalSort(
0848:                                                                        depGraph
0849:                                                                                .keySet(),
0850:                                                                        depGraph);
0851:                                                        deps.putAll(depGraph);
0852:                                                    } catch (final TopologicalSortException tse) {
0853:                                                        final IllegalStateException ise = new IllegalStateException();
0854:                                                        throw (IllegalStateException) ise
0855:                                                                .initCause(tse);
0856:                                                    }
0857:                                                    if (!scanRoots()) {
0858:                                                        CompileWorker.this .work = new Work(
0859:                                                                WorkType.COMPILE_CONT,
0860:                                                                null);
0861:                                                        SourceAccessor
0862:                                                                .getINSTANCE()
0863:                                                                .runSpecialTask(
0864:                                                                        CompileWorker.this ,
0865:                                                                        Source.Priority.MAX);
0866:                                                        continuation = true;
0867:                                                        return null;
0868:                                                    }
0869:                                                }
0870:                                                completed = true;
0871:                                            } finally {
0872:                                                if (!completed && !continuation) {
0873:                                                    resetDirty();
0874:                                                }
0875:                                            }
0876:                                            //                            final ClassIndexManager cim = ClassIndexManager.getDefault();
0877:                                            scannedRoots.removeAll(oldRoots);
0878:                                            deps.keySet().remove(oldRoots);
0879:                                            //if (CLOSE_INDICES) {    // HACK - see #120231                        
0880:                                            //                            for (URL oldRoot : oldRoots) {
0881:                                            //                                cim.removeRoot(oldRoot);
0882:                                            ////                                JavaFileFilterImplementation filter = filters.remove(oldRoot);
0883:                                            ////                                if (filter != null && !filters.values().contains(filter)) {
0884:                                            ////                                    filter.removeChangeListener(filterListener);
0885:                                            ////                                }
0886:                                            //                            }
0887:                                            //}
0888:                                            scannedBinaries
0889:                                                    .removeAll(oldBinaries);
0890:                                            //                            final CachingArchiveProvider cap = CachingArchiveProvider.getDefault();
0891:                                            //if (CLOSE_INDICES) {                            
0892:                                            //                            for (URL oldRoot : oldBinaries) {
0893:                                            //                                cim.removeRoot(oldRoot);
0894:                                            ////                                cap.removeArchive(oldRoot);
0895:                                            //                            }
0896:                                            //}
0897:                                            break;
0898:                                        case COMPILE: {
0899:                                            try {
0900:                                                final SingleRootWork sw = (SingleRootWork) work;
0901:                                                final URL file = sw.getFile();
0902:                                                final URL root = sw.getRoot();
0903:                                                if (sw.isFolder()) {
0904:                                                    handle = ProgressHandleFactory
0905:                                                            .createHandle(NbBundle
0906:                                                                    .getMessage(
0907:                                                                            RepositoryUpdater.class,
0908:                                                                            "MSG_Updating"));
0909:                                                    handle.start();
0910:                                                    try {
0911:                                                        updateFolder(file,
0912:                                                                root, false,
0913:                                                                handle);
0914:                                                    } finally {
0915:                                                        handle.finish();
0916:                                                    }
0917:                                                } else {
0918:                                                    updateFile(file, root);
0919:                                                }
0920:                                                //} catch (Abort abort) {
0921:                                            } catch (Exception abort) {
0922:                                                //Ignore abort
0923:                                            }
0924:                                            break;
0925:                                        }
0926:                                        case DELETE: {
0927:                                            final SingleRootWork sw = (SingleRootWork) work;
0928:                                            final URL file = sw.getFile();
0929:                                            final URL root = sw.getRoot();
0930:                                            delete(file, root, sw.isFolder());
0931:                                            break;
0932:                                        }
0933:                                        case UPDATE_BINARY: {
0934:                                            SingleRootWork sw = (SingleRootWork) work;
0935:                                            final URL file = sw.getFile();
0936:                                            final URL root = sw.getRoot();
0937:                                            updateBinary(file, root);
0938:                                            break;
0939:                                        }
0940:                                        }
0941:                                        return null;
0942:                                    } finally {
0943:                                        if (!continuation) {
0944:                                            synchronized (RepositoryUpdater.this ) {
0945:                                                RepositoryUpdater.this .noSubmited--;
0946:                                                if (RepositoryUpdater.this .noSubmited == 0) {
0947:                                                    RepositoryUpdater.this 
0948:                                                            .notifyAll();
0949:                                                }
0950:                                            }
0951:                                            work.finished();
0952:                                            if (handle != null) {
0953:                                                handle.finish();
0954:                                            }
0955:                                        }
0956:                                    }
0957:                                }
0958:                            });
0959:                }
0960:
0961:                private Map<FileObject, WeakReference<ClassPath>> sourceClassPathsCache = new WeakHashMap<FileObject, WeakReference<ClassPath>>();
0962:
0963:                private ClassPath getBootClassPaths(FileObject file, String type/*, FileObject systemRoot*/) {
0964:                    // Default provider - do this for things like Ruby library files
0965:                    synchronized (this ) {
0966:                        ClassPath cp = null;
0967:                        if (!file.isFolder()) {
0968:                            //file = systemRoot;
0969:                            assert false : file;
0970:                        }
0971:                        if (file.isFolder()) {
0972:                            Reference ref = (Reference) this .sourceClassPathsCache
0973:                                    .get(file);
0974:                            if (ref == null
0975:                                    || (cp = (ClassPath) ref.get()) == null) {
0976:                                cp = ClassPathSupport
0977:                                        .createClassPath(new FileObject[] { file });
0978:                                this .sourceClassPathsCache.put(file,
0979:                                        new WeakReference<ClassPath>(cp));
0980:                            }
0981:                        }
0982:                        return cp;
0983:                    }
0984:                }
0985:
0986:                private void findDependencies(final URL rootURL,
0987:                        final Stack<URL> cycleDetector,
0988:                        final Map<URL, List<URL>> depGraph,
0989:                        final Set<URL> binaries, final boolean useInitialState) {
0990:                    if (useInitialState
0991:                            && RepositoryUpdater.this .scannedRoots
0992:                                    .contains(rootURL)) {
0993:                        this .oldRoots.remove(rootURL);
0994:                        return;
0995:                    }
0996:                    if (depGraph.containsKey(rootURL)) {
0997:                        return;
0998:                    }
0999:                    final FileObject rootFo = URLMapper.findFileObject(rootURL);
1000:                    if (rootFo == null) {
1001:                        return;
1002:                    }
1003:
1004:                    // BEGIN TOR MODIFICATIONS
1005:                    // I don't want to start asking for the ClassPath of directories in the libraries
1006:                    // since these start yielding Java jars etc.
1007:                    if (true) {
1008:                        //if (useInitialState) {
1009:                        depGraph.put(rootURL, new LinkedList<URL>());
1010:
1011:                        if (!RepositoryUpdater.this .scannedBinaries
1012:                                .contains(rootURL)) {
1013:                            binaries.add(rootURL);
1014:                        }
1015:                        oldBinaries.remove(rootURL);
1016:                        //}
1017:                        return;
1018:                    }
1019:                    // END TOR MODIFICATIONS
1020:
1021:                    cycleDetector.push(rootURL);
1022:                    final ClassPath bootPath = ClassPath.getClassPath(rootFo,
1023:                            ClassPath.BOOT);
1024:                    final ClassPath compilePath = ClassPath.getClassPath(
1025:                            rootFo, ClassPath.COMPILE);
1026:                    final ClassPath[] pathsToResolve = new ClassPath[] {
1027:                            bootPath, compilePath };
1028:                    //            ClassPath libraryPath = LanguageRegistry.getInstance().getLibraryPaths();
1029:                    //            final ClassPath[] pathsToResolve =  libraryPath != null ?
1030:                    //                new ClassPath[] {bootPath, compilePath, libraryPath} :
1031:                    //                new ClassPath[] {bootPath,compilePath};
1032:                    final List<URL> deps = new LinkedList<URL>();
1033:                    for (int i = 0; i < pathsToResolve.length; i++) {
1034:                        final ClassPath pathToResolve = pathsToResolve[i];
1035:                        if (pathToResolve != null) {
1036:                            for (ClassPath.Entry entry : pathToResolve
1037:                                    .entries()) {
1038:                                final URL url = entry.getURL();
1039:                                final URL[] sourceRoots = RepositoryUpdater.this .cpImpl
1040:                                        .getSourceRootForBinaryRoot(url,
1041:                                                pathToResolve, false);
1042:                                if (sourceRoots != null) {
1043:                                    for (URL sourceRoot : sourceRoots) {
1044:                                        if (sourceRoot.equals(rootURL)) {
1045:                                            this .ignoreExcludes.add(rootURL);
1046:                                        } else if (!cycleDetector
1047:                                                .contains(sourceRoot)) {
1048:                                            deps.add(sourceRoot);
1049:                                            findDependencies(sourceRoot,
1050:                                                    cycleDetector, depGraph,
1051:                                                    binaries, useInitialState);
1052:                                        }
1053:                                    }
1054:                                } else {
1055:                                    if (useInitialState) {
1056:                                        if (!RepositoryUpdater.this .scannedBinaries
1057:                                                .contains(url)) {
1058:                                            binaries.add(url);
1059:                                        }
1060:                                        oldBinaries.remove(url);
1061:                                    }
1062:                                }
1063:                            }
1064:                        }
1065:                    }
1066:                    depGraph.put(rootURL, deps);
1067:                    cycleDetector.pop();
1068:                }
1069:
1070:                private boolean scanRoots() {
1071:
1072:                    for (Iterator<URL> it = this .newBinaries.iterator(); it
1073:                            .hasNext();) {
1074:                        if (this .canceled.getAndSet(false)) {
1075:                            return false;
1076:                        }
1077:                        final URL rootURL = it.next();
1078:                        try {
1079:                            it.remove();
1080:                            for (IndexerEntry entry : getIndexers()) {
1081:                                Language language = entry.getLanguage();
1082:                                final ClassIndexImpl ci = ClassIndexManager
1083:                                        .get(language).createUsagesQuery(
1084:                                                rootURL, false);
1085:                            }
1086:                            RepositoryUpdater.this .scannedBinaries.add(rootURL);
1087:                            //                    long startT = System.currentTimeMillis();
1088:                            //                    ci.getBinaryAnalyser().analyse(rootURL, handle);
1089:                            //                    long endT = System.currentTimeMillis();
1090:                            //                    if (PERF_TEST) {
1091:                            //                        try {
1092:                            //                            Class c = Class.forName("org.netbeans.performance.test.utilities.LoggingScanClasspath",true,Thread.currentThread().getContextClassLoader()); // NOI18N
1093:                            //                            java.lang.reflect.Method m = c.getMethod("reportScanOfFile", new Class[] {String.class, Long.class}); // NOI18N
1094:                            //                            m.invoke(c.newInstance(), new Object[] {rootURL.toExternalForm(), new Long(endT - startT)});
1095:                            //                        } catch (Exception e) {
1096:                            //                                Exceptions.printStackTrace(e);
1097:                            //                        }                            
1098:                            //                    }
1099:                        } catch (Throwable e) {
1100:                            if (e instanceof  ThreadDeath) {
1101:                                throw (ThreadDeath) e;
1102:                            } else {
1103:                                Exceptions.attachMessage(e, "While scanning: "
1104:                                        + rootURL);
1105:                                Exceptions.printStackTrace(e);
1106:                            }
1107:                        }
1108:                    }
1109:                    for (java.util.ListIterator<URL> it = this .state
1110:                            .listIterator(this .state.size()); it.hasPrevious();) {
1111:                        if (this .canceled.getAndSet(false)) {
1112:                            return false;
1113:                        }
1114:                        try {
1115:                            final URL rootURL = it.previous();
1116:                            it.remove();
1117:                            if (!oldRoots.remove(rootURL)
1118:                                    && !RepositoryUpdater.this .scannedRoots
1119:                                            .contains(rootURL)) {
1120:                                long startT = System.currentTimeMillis();
1121:                                updateFolder(rootURL, rootURL, false, handle);
1122:                                long endT = System.currentTimeMillis();
1123:                                if (PERF_TEST) {
1124:                                    try {
1125:                                        Class c = Class
1126:                                                .forName(
1127:                                                        "org.netbeans.performance.test.utilities.LoggingScanClasspath",
1128:                                                        true,
1129:                                                        Thread
1130:                                                                .currentThread()
1131:                                                                .getContextClassLoader()); // NOI18N
1132:                                        java.lang.reflect.Method m = c
1133:                                                .getMethod("reportScanOfFile",
1134:                                                        new Class[] {
1135:                                                                String.class,
1136:                                                                Long.class }); // NOI18N
1137:                                        m.invoke(c.newInstance(), new Object[] {
1138:                                                rootURL.toExternalForm(),
1139:                                                new Long(endT - startT) });
1140:                                    } catch (Exception e) {
1141:                                        Exceptions.printStackTrace(e);
1142:                                    }
1143:                                }
1144:                                if (PREINDEXING) {
1145:                                    // How do I obtain the data folder for this puppy?
1146:                                    for (Language language : LanguageRegistry
1147:                                            .getInstance()) {
1148:                                        if (language.getIndexer() != null) {
1149:                                            Index.preindex(language, rootURL);
1150:                                        }
1151:                                    }
1152:                                }
1153:                            }
1154:                        } catch (Throwable e) {
1155:                            if (e instanceof  ThreadDeath) {
1156:                                throw (ThreadDeath) e;
1157:                            } else {
1158:                                Exceptions.printStackTrace(e);
1159:                            }
1160:                        }
1161:                    }
1162:                    return true;
1163:                }
1164:
1165:                private void updateFolder(final URL folder, final URL root,
1166:                        boolean clean, final ProgressHandle handle)
1167:                        throws IOException {
1168:                    final FileObject rootFo = URLMapper.findFileObject(root);
1169:                    if (rootFo == null) {
1170:                        return;
1171:                    }
1172:                    if (!rootFo.isFolder()) {
1173:                        LOGGER.warning("Source root has to be a folder: "
1174:                                + FileUtil.getFileDisplayName(rootFo)); // NOI18N
1175:                        return;
1176:                    }
1177:                    ClassPath sourcePath = ClassPath.getClassPath(rootFo,
1178:                            ClassPath.SOURCE);
1179:                    ClassPath bootPath = ClassPath.getClassPath(rootFo,
1180:                            ClassPath.BOOT);
1181:                    ClassPath compilePath = ClassPath.getClassPath(rootFo,
1182:                            ClassPath.COMPILE);
1183:                    final boolean isInitialCompilation = folder.equals(root);
1184:                    if (sourcePath == null || bootPath == null
1185:                            || compilePath == null) {
1186:                        //LOGGER.warning("Ignoring root with no ClassPath: " + FileUtil.getFileDisplayName(rootFo));    // NOI18N
1187:                        //return;
1188:                        ClassPath cp = getBootClassPaths(rootFo,
1189:                                ClassPath.SOURCE);
1190:                        if (sourcePath == null) {
1191:                            sourcePath = cp;
1192:                        }
1193:                        if (bootPath == null) {
1194:                            bootPath = cp;
1195:                        }
1196:                        if (compilePath == null) {
1197:                            compilePath = cp;
1198:                        }
1199:                    }
1200:                    boolean isBoot = isInitialCompilation
1201:                            && ClassIndexManager.isBootRoot(root);
1202:                    if (!isBoot) {
1203:                        String urlString = root.toExternalForm();
1204:                        if (urlString.indexOf("/vendor/") != -1) {
1205:                            isBoot = true;
1206:                        }
1207:                    }
1208:                    /*
1209:                     // XXX This is suspicious
1210:                     if (!clean && isInitialCompilation) {
1211:                     //Initial compilation  debug messages
1212:                     if (RepositoryUpdater.this.scannedRoots.contains(root)) {
1213:                     return;
1214:                     }                
1215:                     LOGGER.fine("Scanning Root: " + FileUtil.getFileDisplayName(rootFo));    //NOI18N
1216:                     }
1217:                     */
1218:                    try {
1219:                        File rootFile = FileUtil.toFile(rootFo);
1220:                        if (rootFile == null) {
1221:                            FileObject jar = FileUtil.getArchiveFile(rootFo);
1222:                            rootFile = FileUtil.toFile(jar);
1223:                            if (rootFile == null) {
1224:                                // Probably a jar, which sometimes ends up in my updateFolder now because the
1225:                                // isBinary stuff etc. isn't working yet
1226:                                return;
1227:                            }
1228:                        }
1229:                        final File folderFile = isInitialCompilation ? rootFile
1230:                                : FileUtil.normalizeFile(new File(URI
1231:                                        .create(folder.toExternalForm())));
1232:                        if (handle != null) {
1233:                            final String message = NbBundle.getMessage(
1234:                                    RepositoryUpdater.class, "MSG_Scannig",
1235:                                    rootFile.getAbsolutePath());
1236:                            handle.setDisplayName(message);
1237:                        }
1238:                        //                //Preprocessor support
1239:                        Object filter = null;
1240:                        //                JavaFileFilterImplementation filter = filters.get(root);
1241:                        //                if (filter == null) {
1242:                        //                    filter = JavaFileFilterQuery.getFilter(rootFo);
1243:                        //                    if (filter != null) {
1244:                        //                        if (!filters.values().contains(filter)) {
1245:                        //                            filter.addChangeListener(filterListener);
1246:                        //                        }
1247:                        //                        filters.put(root, filter);
1248:                        //                    }
1249:                        //                }
1250:                        List<ParserFile> toCompile = new LinkedList<ParserFile>();
1251:                        final Map<String, List<File>> resources = Collections
1252:                                .emptyMap();
1253:                        final LazyFileList children = new LazyFileList(
1254:                                folderFile);
1255:
1256:                        // If this is a boot class path, don't update it
1257:                        boolean isRootFolder = isBoot;
1258:                        // Known Rails user-project exceptions (not recorded as boot roots since 
1259:                        // they are in the user's project directories)
1260:                        if (folderFile.getName().equals("vendor")
1261:                                || folderFile.getName().equals("lib")) { // NOI18N
1262:                            // lib? Won't that mess up my user projects?
1263:                            isRootFolder = true;
1264:                        }
1265:
1266:                        boolean checkUpToDate = false;
1267:                        if (isRootFolder) {
1268:                            if (folderFile.exists() && folderFile.canRead()) {
1269:                                checkUpToDate = true;
1270:                            }
1271:                        }
1272:                        boolean allUpToDate = checkUpToDate;
1273:
1274:                        Map<Language, Map<String, String>> timeStamps = new HashMap<Language, Map<String, String>>();
1275:
1276:                        boolean invalidIndex = false;
1277:                        for (IndexerEntry entry : getIndexers()) {
1278:                            Language language = entry.getLanguage();
1279:                            ClassIndexImpl uqImpl = ClassIndexManager.get(
1280:                                    language).createUsagesQuery(root, true);
1281:                            assert uqImpl != null;
1282:                            SourceAnalyser sa = uqImpl.getSourceAnalyser();
1283:                            assert sa != null;
1284:                            if (checkUpToDate
1285:                                    && !sa.isUpToDate(null, folderFile
1286:                                            .lastModified())) {
1287:                                allUpToDate = false;
1288:                            } else if (isInitialCompilation) {
1289:                                if (!sa.isValid()) {
1290:                                    invalidIndex = true;
1291:                                    allUpToDate = false;
1292:                                } else { //if (!isBoot) {
1293:                                    final ClassIndexImpl ci = ClassIndexManager
1294:                                            .get(language).getUsagesQuery(root);
1295:                                    if (ci != null) {
1296:                                        Map<String, String> ts = ci
1297:                                                .getTimeStamps();
1298:                                        if (ts != null && ts.size() > 0) {
1299:                                            timeStamps.put(language, ts);
1300:                                        }
1301:                                    }
1302:                                }
1303:                            }
1304:                        }
1305:
1306:                        if (allUpToDate) {
1307:                            return;
1308:                        }
1309:
1310:                        if (timeStamps.size() == 0) {
1311:                            timeStamps = null;
1312:                        }
1313:
1314:                        //                Set<File> rs = new HashSet<File> ();
1315:                        ClassPath.Entry entry = null;
1316:                        final ClasspathInfo cpInfo;
1317:                        if (!this .ignoreExcludes.contains(root)) {
1318:                            entry = getClassPathEntry(sourcePath, root);
1319:                            cpInfo = ClasspathInfoAccessor.INSTANCE.create(
1320:                                    bootPath, compilePath, sourcePath, filter,
1321:                                    true, false);
1322:                        } else {
1323:                            cpInfo = ClasspathInfoAccessor.INSTANCE.create(
1324:                                    bootPath, compilePath, sourcePath, filter,
1325:                                    true, true);
1326:                        }
1327:
1328:                        //                Set<ElementHandle<TypeElement>> removed = isInitialCompilation ? null : new HashSet<ElementHandle<TypeElement>> ();
1329:                        //                Set<ElementHandle<TypeElement>> added =   isInitialCompilation ? null : new HashSet<ElementHandle<TypeElement>> ();
1330:                        Set removed = null;
1331:                        Set added = null;
1332:                        for (File child : children) {
1333:                            String offset = FileObjects.getRelativePath(
1334:                                    rootFile, child);
1335:                            if (entry == null
1336:                                    || entry.includes(offset.replace(
1337:                                            File.separatorChar, '/'))) {
1338:                                if (invalidIndex
1339:                                        || clean
1340:                                        || dirtyCrossFiles
1341:                                                .remove(child.toURI())) {
1342:                                    toCompile.add(FileObjects
1343:                                            .fileFileObject(child, rootFile,
1344:                                                    isBoot, null/* filter*/));
1345:                                } else {
1346:                                    final int index = offset.lastIndexOf('.'); //NOI18N
1347:                                    if (index > -1) {
1348:                                        offset = offset.substring(0, index);
1349:                                    }
1350:                                    List<File> files = resources.remove(offset);
1351:                                    if (files == null) {
1352:                                        toCompile
1353:                                                .add(FileObjects
1354:                                                        .fileFileObject(child,
1355:                                                                rootFile,
1356:                                                                isBoot, null/*filter*/));
1357:                                    } else {
1358:                                        //                                boolean rsf = files.get(0).getName().endsWith(FileObjects.RS);
1359:                                        if (files.get(0).lastModified() < child
1360:                                                .lastModified()) {
1361:                                            toCompile.add(FileObjects
1362:                                                    .fileFileObject(child,
1363:                                                            rootFile, isBoot,
1364:                                                            null/*filter*/));
1365:                                            for (File toDelete : files) {
1366:                                                toDelete.delete();
1367:                                                //                                        if (rsf) {                                    
1368:                                                //                                            rsf = false;
1369:                                                //                                        }
1370:                                                //                                        else {
1371:                                                //                                            String className = FileObjects.getBinaryName(toDelete,classCache);
1372:                                                //                                            sa.delete(toDelete);
1373:                                                //                                            if (removed != null) {
1374:                                                //                                                removed.add(ElementHandleAccessor.INSTANCE.create(ElementKind.OTHER, className));
1375:                                                //                                            }
1376:                                            }
1377:                                            //                                    }
1378:                                            //                                }
1379:                                            //                                else if (rsf) {
1380:                                            //                                    files.remove(0);
1381:                                            //                                    rs.addAll(files);
1382:                                        }
1383:                                    }
1384:                                }
1385:                            }
1386:                        }
1387:                        for (List<File> files : resources.values()) {
1388:                            for (File toDelete : files) {
1389:                                //                      if (!rs.contains(toDelete)) {
1390:                                toDelete.delete();
1391:                                if (toDelete.getName()
1392:                                        .endsWith(FileObjects.SIG)) {
1393:                                    //String className = FileObjects.getBinaryName(toDelete,classCache);                        
1394:                                    //sa.delete(className);
1395:                                    //                                sa.delete(toDelete);
1396:                                    //                                if (removed != null) {
1397:                                    //                                    removed.add(ElementHandleAccessor.INSTANCE.create(ElementKind.OTHER, className));
1398:                                    //                                }
1399:                                }
1400:                                //                        }
1401:                            }
1402:                        }
1403:                        if (!toCompile.isEmpty()) {
1404:                            if (handle != null) {
1405:                                // BEGIN TOR MODIFICATIONS
1406:                                // Show message for "indexing" rather than compiling since I'm not keeping trees around etc - it's
1407:                                // all used to populate Lucene at this point.
1408:                                //final String message = NbBundle.getMessage(RepositoryUpdater.class,"MSG_BackgroundCompile",rootFile.getAbsolutePath());
1409:                                String path = rootFile.getAbsolutePath();
1410:                                // Shorten path by prefix to ruby location if possible
1411:                                int rubyIndex = path.indexOf("jruby-1.1RC1");
1412:                                if (rubyIndex != -1) {
1413:                                    path = path.substring(rubyIndex);
1414:                                }
1415:                                final String message = NbBundle.getMessage(
1416:                                        RepositoryUpdater.class,
1417:                                        "MSG_Analyzing", path);
1418:                                handle.setDisplayName(message);
1419:                            }
1420:                            batchCompile(toCompile, rootFo, cpInfo, /*sa,*/
1421:                                    root, dirtyCrossFiles, added, handle,
1422:                                    timeStamps);
1423:                        }
1424:                        // store is a noop anyway                
1425:                        //                sa.store();
1426:
1427:                        //                if (added != null) {
1428:                        //                    assert removed != null;
1429:                        //                    Set<ElementHandle<TypeElement>> _at = new HashSet<ElementHandle<TypeElement>> (added);      //Added
1430:                        //                    Set<ElementHandle<TypeElement>> _rt = new HashSet<ElementHandle<TypeElement>> (removed);    //Removed
1431:                        //                    _at.removeAll(removed);
1432:                        //                    _rt.removeAll(added);
1433:                        //                    added.retainAll(removed);                                                                   //Changed
1434:                        //                    uqImpl.typesEvent(_at.isEmpty() ? null : new ClassIndexImplEvent(uqImpl, _at),
1435:                        //                            _rt.isEmpty() ? null : new ClassIndexImplEvent (uqImpl,_rt), 
1436:                        //                            added.isEmpty() ? null : new ClassIndexImplEvent (uqImpl,added));
1437:                        //                }
1438:                    } finally {
1439:                        if (!clean && isInitialCompilation) {
1440:                            RepositoryUpdater.this .scannedRoots.add(root);
1441:                        }
1442:                    }
1443:                }
1444:
1445:                private List<Language> getApplicableIndexers(String mimeType) {
1446:                    List<Language> languages = null;
1447:                    for (Language language : LanguageRegistry.getInstance()
1448:                            .getApplicableLanguages(mimeType)) {
1449:                        if (language.getIndexer() == null) {
1450:                            continue;
1451:                        }
1452:
1453:                        if (languages == null) {
1454:                            languages = new ArrayList<Language>(5);
1455:                        }
1456:                        languages.add(language);
1457:                    }
1458:
1459:                    return languages != null ? languages : Collections
1460:                            .<Language> emptyList();
1461:                }
1462:
1463:                private void updateFile(final URL file, final URL root)
1464:                        throws IOException {
1465:                    final FileObject fo = URLMapper.findFileObject(file);
1466:                    if (fo == null) {
1467:                        return;
1468:                    }
1469:
1470:                    List<Language> languages = getApplicableIndexers(fo
1471:                            .getMIMEType());
1472:                    if (languages.size() > 0) {
1473:                        final File rootFile = FileUtil.normalizeFile(new File(
1474:                                URI.create(root.toExternalForm())));
1475:                        final File fileFile = FileUtil.toFile(fo);
1476:                        ParserFile active = FileObjects.fileFileObject(
1477:                                fileFile, rootFile, false, null/*filter*/);
1478:                        ParserFile[] activeList = new ParserFile[] { active };
1479:                        ClasspathInfo cpInfo = ClasspathInfoAccessor.INSTANCE
1480:                                .create(fo, null/*filter*/, true, false);
1481:                        ClassPath.Entry entry = getClassPathEntry(cpInfo
1482:                                .getClassPath(ClasspathInfo.PathKind.SOURCE),
1483:                                root);
1484:                        boolean scan = (entry == null || entry.includes(fo));
1485:                        String sourceLevel = scan ? SourceLevelQuery
1486:                                .getSourceLevel(fo) : null;
1487:                        for (Language language : languages) {
1488:                            assert "file".equals(root.getProtocol()) : "Unexpected protocol of URL: "
1489:                                    + root; //NOI18N
1490:                            final ClassIndexImpl uqImpl = ClassIndexManager
1491:                                    .get(language)
1492:                                    .createUsagesQuery(root, true);
1493:                            if (uqImpl != null) {
1494:                                uqImpl.setDirty(null);
1495:                                //                final JavaFileFilterImplementation filter = JavaFileFilterQuery.getFilter(fo);
1496:                                //final File classCache = Index.getClassFolder (rootFile);
1497:                                //final Map <String,List<File>> resources = getAllClassFiles (classCache, FileObjects.getRelativePath(rootFile, fileFile.getParentFile()),false);
1498:                                //                String offset = FileObjects.getRelativePath (rootFile,fileFile);
1499:                                //                final int index = offset.lastIndexOf('.');  //NOI18N
1500:                                //                if (index > -1) {
1501:                                //                    offset = offset.substring(0,index);
1502:                                //                }
1503:                                //List<File> files = resources.remove (offset);                
1504:                                SourceAnalyser sa = uqImpl.getSourceAnalyser();
1505:                                assert sa != null;
1506:                                //final Set<ElementHandle<TypeElement>> added = new HashSet<ElementHandle<TypeElement>>();
1507:                                //final Set<ElementHandle<TypeElement>> removed = new HashSet <ElementHandle<TypeElement>> ();
1508:                                // TODO: Handle deletions; is this only used for th sig files?
1509:                                //                if (files != null) {
1510:                                //                    for (File toDelete : files) {
1511:                                //                        toDelete.delete();
1512:                                //                        if (toDelete.getName().endsWith(FileObjects.SIG)) {
1513:                                //                            String className = FileObjects.getBinaryName (toDelete,classCache);                                                           
1514:                                //                            sa.delete (className);
1515:                                //                            removed.add (ElementHandleAccessor.INSTANCE.create(ElementKind.OTHER, className));
1516:                                //                        }
1517:                                //                    }
1518:                                //                }
1519:                                //                else {
1520:                                //                    sa.delete(FileObjects.convertFolder2Package(offset, '/'));  //NOI18N
1521:                                //                }
1522:                                if (scan) {
1523:                                    final CompilerListener listener = new CompilerListener();
1524:                                    //final JavaFileManager fm = ClasspathInfoAccessor.INSTANCE.getFileManager(cpInfo);                
1525:                                    //JavaFileObject active = FileObjects.fileFileObject(fileFile, rootFile, filter);
1526:                                    //JavacTaskImpl jt = JavaSourceAccessor.getINSTANCE().createJavacTask(cpInfo, listener, sourceLevel);
1527:                                    ParserTaskImpl jt = SourceAccessor
1528:                                            .getINSTANCE().createParserTask(
1529:                                                    language, cpInfo,
1530:                                                    sourceLevel);
1531:                                    //jt.setTaskListener(listener);
1532:                                    jt.setParseListener(listener);
1533:                                    //Iterable<? extends CompilationUnitTree> trees = jt.parse(new JavaFileObject[] {active});
1534:                                    Iterable<ParserResult> trees = jt
1535:                                            .parse(activeList);
1536:                                    //jt.enter();            
1537:                                    //jt.analyze ();
1538:                                    //dumpClasses(listener.getEnteredTypes(), fm, root.toExternalForm(), null, ...
1539:                                    //sa.analyse (trees, jt, fm, active, added);
1540:                                    sa.analyse(language, trees, jt, /*fm,*/
1541:                                            active);
1542:
1543:                                    listener.cleanDiagnostics();
1544:                                }
1545:                                //                sa.store();
1546:                                //                Set<ElementHandle<TypeElement>> _at = new HashSet<ElementHandle<TypeElement>> (added);      //Added
1547:                                //                Set<ElementHandle<TypeElement>> _rt = new HashSet<ElementHandle<TypeElement>> (removed);    //Removed
1548:                                //                _at.removeAll(removed);
1549:                                //                _rt.removeAll(added);
1550:                                //                added.retainAll(removed);                                                                   //Changed
1551:                                //                uqImpl.typesEvent(_at.isEmpty() ? null : new ClassIndexImplEvent(uqImpl, _at),
1552:                                //                        _rt.isEmpty() ? null : new ClassIndexImplEvent(uqImpl,_rt), 
1553:                                //                        added.isEmpty() ? null : new ClassIndexImplEvent(uqImpl,added));                
1554:                            }
1555:                        }
1556:
1557:                        GsfTaskProvider.refresh(fo);
1558:                    }
1559:                }
1560:
1561:                private void delete(final URL file, final URL root,
1562:                        final boolean folder) throws IOException {
1563:                    assert "file".equals(root.getProtocol()) : "Unexpected protocol of URL: "
1564:                            + root; //NOI18N
1565:                    final File rootFile = FileUtil.normalizeFile(new File(URI
1566:                            .create(root.toExternalForm())));
1567:                    assert "file".equals(file.getProtocol()) : "Unexpected protocol of URL: "
1568:                            + file; //NOI18N
1569:                    final File fileFile = FileUtil.normalizeFile(new File(URI
1570:                            .create(file.toExternalForm())));
1571:                    final String offset = FileObjects.getRelativePath(rootFile,
1572:                            fileFile);
1573:                    assert offset != null && offset.length() > 0 : String
1574:                            .format("File %s not under root %s ", fileFile
1575:                                    .getAbsolutePath(), rootFile
1576:                                    .getAbsolutePath()); // NOI18N                        
1577:
1578:                    boolean platform = false;
1579:                    ParserFile parserFile = FileObjects.fileFileObject(
1580:                            fileFile, rootFile, platform, null);
1581:
1582:                    for (Language language : LanguageRegistry.getInstance()) {
1583:                        // I have to iterate over all indexer languages here - I can't call
1584:                        // getApplicableIndexers() since I don't have the mime type for 
1585:                        // deleted files (and asking for it just returns content/unknown)
1586:                        if (language.getIndexer() == null) {
1587:                            continue;
1588:                        }
1589:                        final ClassIndexImpl uqImpl = ClassIndexManager.get(
1590:                                language).createUsagesQuery(root, true);
1591:                        assert uqImpl != null;
1592:                        final SourceAnalyser sa = uqImpl.getSourceAnalyser();
1593:                        assert sa != null;
1594:                        sa.delete(parserFile);
1595:                    }
1596:                    //            
1597:                    //            
1598:                    //            final File classCache = Index.getClassFolder (rootFile);
1599:                    //            File[] affectedFiles = null;
1600:                    //            if (folder) {
1601:                    //                final File container = new File (classCache, offset);
1602:                    //                affectedFiles = container.listFiles();
1603:                    //            }
1604:                    //            else {
1605:                    //                int slashIndex = offset.lastIndexOf (File.separatorChar);
1606:                    //                int dotIndex = offset.lastIndexOf('.');     //NOI18N
1607:                    //                final File container = slashIndex == -1 ? classCache : new File (classCache,offset.substring(0,slashIndex));
1608:                    //                final String name = offset.substring(slashIndex+1, dotIndex);
1609:                    //                final String[] patterns = new String[] {
1610:                    //                  name + '.',
1611:                    //                  name + '$'
1612:                    //                };
1613:                    //                final File[] content  = container.listFiles();
1614:                    //                if (content != null) {
1615:                    //                    final List<File> result = new ArrayList<File>(content.length);
1616:                    //                    for (File f : content) {
1617:                    //                        final String fname = f.getName();
1618:                    //                        if (fname.startsWith(patterns[0]) || fname.startsWith(patterns[1])) {
1619:                    //                            result.add(f);
1620:                    //                        }
1621:                    //                    }
1622:                    //                    affectedFiles = result.toArray(new File[result.size()]);
1623:                    //                }
1624:                    //            }
1625:                    //            if (affectedFiles != null && affectedFiles.length > 0) {
1626:                    ////                Set<ElementHandle<TypeElement>> removed = new HashSet<ElementHandle<TypeElement>>();
1627:                    //                final ClassIndexImpl uqImpl = ClassIndexManager.getDefault().createUsagesQuery(root, true);
1628:                    //                assert uqImpl != null;                
1629:                    //                final SourceAnalyser sa = uqImpl.getSourceAnalyser();
1630:                    //                assert sa != null;
1631:                    //                for (File f : affectedFiles) {
1632:                    ////                    if (f.getName().endsWith(FileObjects.RS)) {
1633:                    ////                        List<File> rsFiles = new LinkedList<File>();
1634:                    ////                        readRSFile(f, classCache, rsFiles);
1635:                    ////                        for (File rsf : rsFiles) {
1636:                    ////                            String className = FileObjects.getBinaryName (rsf,classCache);                                                                        
1637:                    ////                            sa.delete (className);
1638:                    ////                            removed.add(ElementHandleAccessor.INSTANCE.create(ElementKind.OTHER, className));
1639:                    ////                            rsf.delete();
1640:                    ////                        }
1641:                    ////                    }
1642:                    ////                    else {
1643:                    ////                        String className = FileObjects.getBinaryName (f,classCache);                                                                        
1644:                    ////                        sa.delete (className);
1645:                    //                    sa.delete(f);
1646:                    ////                        removed.add(ElementHandleAccessor.INSTANCE.create(ElementKind.OTHER, className));
1647:                    ////                    }
1648:                    //                    f.delete();                    
1649:                    //                }
1650:                    //                sa.store();                
1651:                    ////                uqImpl.typesEvent(null,new ClassIndexImplEvent(uqImpl, removed), null);
1652:                    //            }
1653:                }
1654:
1655:                private void updateBinary(final URL file, final URL root)
1656:                        throws IOException {
1657:                    ////            CachingArchiveProvider.getDefault().clearArchive(root);                       
1658:                    //            File cacheFolder = Index.getClassFolder(root);
1659:                    //            FileObjects.deleteRecursively(cacheFolder);
1660:                    //            final BinaryAnalyser ba = ClassIndexManager.getDefault().createUsagesQuery(root, false).getBinaryAnalyser();
1661:                    //            ba.analyse(root, handle);
1662:                }
1663:            }
1664:
1665:            static class LazyFileList implements  Iterable<File> {
1666:
1667:                private File root;
1668:
1669:                public LazyFileList(final File root) {
1670:                    assert root != null;
1671:                    this .root = root;
1672:                }
1673:
1674:                public Iterator<File> iterator() {
1675:                    if (!root.exists()) {
1676:                        return Collections.<File> emptySet().iterator();
1677:                    }
1678:                    return new It(this .root);
1679:                }
1680:
1681:                private class It implements  Iterator<File> {
1682:
1683:                    private final List<File> toDo = new LinkedList<File>();
1684:
1685:                    public It(File root) {
1686:
1687:                        //                // Special case: Rails on some systems (such as debian)
1688:                        //                // creates symbolic links in the vendor directory back into Rails;
1689:                        //                // I don't want to visit these links. 
1690:                        //                // Arguably I should do this for all dirs - but it's a performance issue,
1691:                        //                // and one I want to investigate more closely before making large changes;
1692:                        //                // this specific fix addresses a serious recorded issue (93019)
1693:                        //                if (root.getName().equals("vendor")) { // NOI18N
1694:                        //                    ArrayList<File> list = new ArrayList<File>();
1695:                        //                    for (File f : root.listFiles()) {
1696:                        //                        
1697:                        //                        // Skip vendor/rails - this is really a library which should
1698:                        //                        // be matching other installations.
1699:                        //                        // Ugh... I shouldn't skip it if I don't have it in the gems!
1700:                        //                        if (skipVendorRails && f.getName().equals("rails")) { // NOI18N
1701:                        //                            continue;
1702:                        //                        }
1703:                        //
1704:                        //                        try {
1705:                        //                            // See JDK issue 4042001 - need symbolic link support.
1706:                        //                            // Workaround which will work in this scenario is a
1707:                        //                            // to compare canonical paths with absolute paths
1708:                        //                            if (f.getAbsolutePath().equals(f.getCanonicalPath())) {
1709:                        //                                list.add(f);
1710:                        //                            }
1711:                        //                        } catch (IOException ioe) {
1712:                        //                            Exceptions.printStackTrace(ioe);
1713:                        //                        }
1714:                        //                    }
1715:                        //                    this.toDo.addAll(list);
1716:                        //                } else {
1717:                        // Normal path
1718:
1719:                        this .toDo.addAll(java.util.Arrays.asList(root
1720:                                .listFiles()));
1721:                        //                }
1722:                    }
1723:
1724:                    public boolean hasNext() {
1725:                        while (!toDo.isEmpty()) {
1726:                            File f = toDo.remove(0);
1727:                            final String name = f.getName();
1728:                            if (f.isDirectory()
1729:                                    && !ignoredDirectories.contains(name)/* && Utilities.isJavaIdentifier(name)*/) {
1730:                                File[] content = f.listFiles();
1731:                                for (int i = 0, j = 0; i < content.length; i++) {
1732:                                    f = content[i];
1733:                                    if (f.isFile()) {
1734:                                        this .toDo.add(j++, f);
1735:                                    } else {
1736:                                        this .toDo.add(f);
1737:                                    }
1738:                                }
1739:                            } else { // XXX How do I decide if it's a reasonable name?
1740:                            //                        System.out.println("Should we scan " + name + "?");
1741:                            //                    else if (name.endsWith('.'+JavaDataLoader.JAVA_EXTENSION) && !PACKAGE_INFO.equals(name) && f.length()>0) { //NOI18N
1742:                                toDo.add(0, f);
1743:                                return true;
1744:                            }
1745:                        }
1746:                        return false;
1747:                    }
1748:
1749:                    public File next() {
1750:                        return toDo.remove(0);
1751:                    }
1752:
1753:                    public void remove() {
1754:                        throw new UnsupportedOperationException();
1755:                    }
1756:
1757:                }
1758:            }
1759:
1760:            private final class Delay {
1761:
1762:                private final Timer timer;
1763:                private final List<Work> tasks;
1764:
1765:                public Delay() {
1766:                    this .timer = new Timer(RepositoryUpdater.class.getName());
1767:                    this .tasks = new LinkedList<Work>();
1768:                }
1769:
1770:                public synchronized void post(final Work work) {
1771:                    assert work != null;
1772:                    this .tasks.add(work);
1773:                    this .timer.schedule(new DelayTask(work), DELAY);
1774:                }
1775:
1776:                public void cancel() {
1777:                    Work[] toCancel;
1778:                    synchronized (this ) {
1779:                        toCancel = this .tasks.toArray(new Work[this .tasks
1780:                                .size()]);
1781:                    }
1782:                    for (Work w : toCancel) {
1783:                        if (w.workType == WorkType.COMPILE) {
1784:                            w = new SingleRootWork(WorkType.DELETE,
1785:                                    ((SingleRootWork) w).file,
1786:                                    ((SingleRootWork) w).root,
1787:                                    ((SingleRootWork) w).isFolder, w.latch);
1788:                        }
1789:                        CompileWorker cw = new CompileWorker(w);
1790:                        try {
1791:                            cw.run(null);
1792:                        } catch (IOException ioe) {
1793:                            Exceptions.printStackTrace(ioe);
1794:                        }
1795:                    }
1796:                }
1797:
1798:                private class DelayTask extends TimerTask {
1799:
1800:                    final Work work;
1801:
1802:                    public DelayTask(final Work work) {
1803:                        this .work = work;
1804:                    }
1805:
1806:                    public void run() {
1807:                        submit(work);
1808:                        synchronized (Delay.this ) {
1809:                            Delay.this .tasks.remove(work);
1810:                        }
1811:                    }
1812:
1813:                    public @Override
1814:                    boolean cancel() {
1815:                        boolean retValue = super .cancel();
1816:                        if (retValue) {
1817:                            synchronized (Delay.this ) {
1818:                                Delay.this .tasks.remove(work);
1819:                            }
1820:                        }
1821:                        return retValue;
1822:                    }
1823:                }
1824:            }
1825:
1826:            private static class CompilerListener implements 
1827:                    /*DiagnosticListener<JavaFileObject>,*/LowMemoryListener,
1828:                    ParseListener {
1829:
1830:                final List<Error> errors = new LinkedList<Error>();
1831:                final List<Error> warnings = new LinkedList<Error>();
1832:                //        final List<ClassSymbol> justEntered = new LinkedList<ClassSymbol> ();
1833:                final List<ParserResult> justEntered = new LinkedList<ParserResult>();
1834:                final AtomicBoolean lowMemory = new AtomicBoolean();
1835:
1836:                //        
1837:                void cleanDiagnostics() {
1838:                    if (!this .errors.isEmpty()) {
1839:                        if (LOGGER.isLoggable(Level.FINE)) {
1840:                            for (Error msg : this .errors) {
1841:                                LOGGER.fine(msg.toString()); //NOI18N
1842:                            }
1843:                        }
1844:                        this .errors.clear();
1845:                    }
1846:                    if (!this .warnings.isEmpty()) {
1847:                        if (LOGGER.isLoggable(Level.FINE)) {
1848:                            for (Error msg : this .warnings) {
1849:                                LOGGER.fine(msg.toString()); //NOI18N
1850:                            }
1851:                        }
1852:                        this .warnings.clear();
1853:                    }
1854:                    this .justEntered.clear();
1855:                }
1856:
1857:                List<ParserResult> getEnteredTypes() {
1858:                    List<ParserResult> result = new ArrayList<ParserResult>(
1859:                            this .justEntered);
1860:                    this .justEntered.clear();
1861:                    return result;
1862:                }
1863:
1864:                public void error(Error error) {
1865:                    if (error.getSeverity() == Severity.ERROR) {
1866:                        this .errors.add(error);
1867:                    } else {
1868:                        this .warnings.add(error);
1869:                    }
1870:                }
1871:
1872:                public void exception(Exception exception) {
1873:                }
1874:
1875:                //
1876:                //        public void report(final Diagnostic diagnosticMessage) {
1877:                //            Diagnostic.Kind kind = diagnosticMessage.getKind();
1878:                //            if ( kind == Diagnostic.Kind.ERROR) {
1879:                //                this.errors.add (diagnosticMessage);
1880:                //            }
1881:                //            else if (kind == Diagnostic.Kind.WARNING
1882:                //                   ||kind == Diagnostic.Kind.MANDATORY_WARNING) {
1883:                //                this.warnings.add (diagnosticMessage);
1884:                //            }
1885:                //        }
1886:                //        
1887:                public void started(ParseEvent e) {
1888:
1889:                }
1890:
1891:                public void finished(ParseEvent event) {
1892:                    if (event.getKind() == ParseEvent.Kind.PARSE /*ENTER*/) {
1893:                        //final CompilationUnitTree unit = event.getCompilationUnit();
1894:                        final ParserResult result = event.getResult();
1895:                        if (result != null) {
1896:                            this .justEntered.add(result);
1897:                        }
1898:                        //                
1899:                        //                for (Tree typeTree : unit.getTypeDecls()) {
1900:                        //                    if (typeTree instanceof JCTree.JCClassDecl) {       //May be a JCTree.JCExpressionStatement in case of an error
1901:                        //                        ClassSymbol sym = ((JCTree.JCClassDecl)typeTree).sym;
1902:                        //                        if (sym != null) {
1903:                        //                            if (sym.sourcefile == null) {
1904:                        //                                sym.sourcefile = event.getSourceFile();
1905:                        //                            }
1906:                        //                            this.justEntered.add(sym);
1907:                        //                        }
1908:                        //                    }          
1909:                        //                }
1910:                    }
1911:                }
1912:
1913:                public void lowMemory(final LowMemoryEvent event) {
1914:                    this .lowMemory.set(true);
1915:                }
1916:            }
1917:
1918:            public static void batchCompile(final List<ParserFile> toCompile,
1919:                    final FileObject rootFo, ClasspathInfo cpInfo,
1920:                    /*final ClasspathInfo cpInfo,*/URL root, /*final SourceAnalyser sa,*/
1921:                    final Set<URI> dirtyFiles,
1922:                    final Set/*<? super  ElementHandle<TypeElement>>*/added,
1923:                    ProgressHandle handle,
1924:                    Map<Language, Map<String, String>> timeStamps)
1925:                    throws IOException {
1926:                assert toCompile != null;
1927:                assert rootFo != null;
1928:                assert cpInfo != null;
1929:                ParserFile active = null;
1930:                //final JavaFileManager fileManager = ClasspathInfoAccessor.INSTANCE.getFileManager(cpInfo);
1931:                final CompilerListener listener = new CompilerListener();
1932:                LowMemoryNotifier.getDefault().addLowMemoryListener(listener);
1933:                try {
1934:                    ParserTaskImpl jt = null;
1935:
1936:                    try {
1937:                        List<ParserFile> bigFiles = new LinkedList<ParserFile>();
1938:                        int state = 0; // TODO: Document what these states mean
1939:                        boolean isBigFile = false;
1940:                        final String sourceLevel = SourceLevelQuery
1941:                                .getSourceLevel(rootFo);
1942:                        int fileNumber = 0;
1943:                        int fileCount = toCompile.size();
1944:                        if (fileCount > 0) {
1945:                            handle.switchToDeterminate(fileCount);
1946:                        }
1947:                        allFiles: while (!toCompile.isEmpty()
1948:                                || !bigFiles.isEmpty() || active != null) {
1949:                            try {
1950:                                if (listener.lowMemory.getAndSet(false)) {
1951:                                    if (jt != null) {
1952:                                        jt.finish();
1953:                                    }
1954:                                    jt = null;
1955:                                    if (state == 1) {
1956:                                        break;
1957:                                    } else {
1958:                                        state = 1;
1959:                                    }
1960:                                    System.gc();
1961:                                    continue;
1962:                                }
1963:                                if (active == null) {
1964:                                    if (!toCompile.isEmpty()) {
1965:                                        active = toCompile.remove(0);
1966:                                        isBigFile = false;
1967:                                    } else {
1968:                                        active = bigFiles.remove(0);
1969:                                        isBigFile = true;
1970:                                    }
1971:                                }
1972:
1973:                                if (handle != null && active != null) {
1974:                                    if (fileCount > 0
1975:                                            && fileNumber <= fileCount) {
1976:                                        handle.progress(fileNumber);
1977:                                    }
1978:                                    fileNumber++;
1979:                                }
1980:
1981:                                // Change from what's going on in the Retouche updater:
1982:                                // We could have many language implementations that want to index this root;
1983:                                // we need to iterate through them and let each one of them index if they
1984:                                // want to.
1985:                                List<IndexerEntry> indexers = getIndexers();
1986:                                assert indexers instanceof  RandomAccess;
1987:                                // We're gonna do this for every file in the filesystem - do cheaper iteration
1988:                                // using indices rather than iterators
1989:                                Language language = null;
1990:                                for (int in = 0; in < indexers.size(); in++) {
1991:                                    IndexerEntry entry = indexers.get(in);
1992:                                    Indexer indexer = entry.getIndexer();
1993:                                    if (!indexer.isIndexable(active)) {
1994:                                        continue;
1995:                                    }
1996:
1997:                                    language = entry.getLanguage();
1998:                                    if (timeStamps != null) {
1999:                                        Map<String, String> ts = timeStamps
2000:                                                .get(language);
2001:                                        if (ts != null) {
2002:                                            File file = active.getFile();
2003:                                            String url = indexer
2004:                                                    .getPersistentUrl(file);
2005:                                            String timeStampString = ts
2006:                                                    .get(url);
2007:                                            if (timeStampString != null) {
2008:                                                try {
2009:                                                    long timeStamp = DateTools
2010:                                                            .stringToTime(timeStampString);
2011:                                                    if (file.lastModified() <= timeStamp) {
2012:                                                        state = 0;
2013:                                                        active = null;
2014:                                                        listener
2015:                                                                .cleanDiagnostics();
2016:                                                        continue allFiles;
2017:                                                    }
2018:                                                } catch (ParseException ex) {
2019:                                                    Exceptions
2020:                                                            .printStackTrace(ex);
2021:                                                }
2022:                                            }
2023:                                        }
2024:                                    }
2025:
2026:                                    // Cache parser tasks per indexer
2027:                                    jt = entry.getParserTask();
2028:
2029:                                    if (jt == null) {
2030:                                        jt = SourceAccessor.getINSTANCE()
2031:                                                .createParserTask(language,
2032:                                                        cpInfo/*, listener*/,
2033:                                                        sourceLevel);
2034:                                        jt.setParseListener(listener);
2035:                                        entry.setParserTask(jt);
2036:                                        LOGGER
2037:                                                .fine("Created new ParserTask for: "
2038:                                                        + FileUtil
2039:                                                                .getFileDisplayName(rootFo)); //NOI18N
2040:                                    }
2041:                                }
2042:
2043:                                // Not an interesting source - such as a .zip file, a .gif file etc.
2044:                                if (language == null) {
2045:                                    state = 0;
2046:                                    active = null;
2047:                                    listener.cleanDiagnostics();
2048:                                    continue;
2049:                                }
2050:
2051:                                Iterable<ParserResult> trees = jt
2052:                                        .parse(new ParserFile[] { active });
2053:                                if (listener.lowMemory.getAndSet(false)) {
2054:                                    jt.finish();
2055:                                    jt = null;
2056:                                    listener.cleanDiagnostics();
2057:                                    trees = null;
2058:                                    if (state == 1) {
2059:                                        if (isBigFile) {
2060:                                            break;
2061:                                        } else {
2062:                                            bigFiles.add(active);
2063:                                            active = null;
2064:                                            state = 0;
2065:                                        }
2066:                                    } else {
2067:                                        state = 1;
2068:                                    }
2069:                                    System.gc();
2070:                                    continue;
2071:                                }
2072:                                //                        Iterable<? extends TypeElement> types = jt.enterTrees(trees);
2073:                                //                        dumpClasses (listener.getEnteredTypes(),fileManager,
2074:                                //                                rootFo.getURL().toExternalForm(), dirtyFiles,
2075:                                //                                com.sun.tools.javac.code.Types.instance(jt.getContext()),
2076:                                //                                com.sun.tools.javac.util.Name.Table.instance(jt.getContext()));
2077:                                //                        if (listener.lowMemory.getAndSet(false)) {
2078:                                //                            jt.finish();
2079:                                //                            jt = null;
2080:                                //                            listener.cleanDiagnostics();
2081:                                //                            trees = null;
2082:                                //                            types = null;
2083:                                //                            if (state == 1) {
2084:                                //                                if (isBigFile) {
2085:                                //                                    break;
2086:                                //                                } else {
2087:                                //                                    bigFiles.add(active);
2088:                                //                                    active = null;
2089:                                //                                    state = 0;
2090:                                //                                }
2091:                                //                            } else {
2092:                                //                                state = 1;
2093:                                //                            }
2094:                                //                            System.gc();
2095:                                //                            continue;
2096:                                //                        }                        
2097:                                //                        final JavaCompiler jc = JavaCompiler.instance(jt.getContext());
2098:                                //                        final JavaFileObject finalActive = active;
2099:                                //                        Filter f = new Filter() {
2100:                                //                            public void process(Env<AttrContext> env) {
2101:                                //                                try {
2102:                                //                                    jc.attribute(env);
2103:                                //                                } catch (Throwable t) {
2104:                                //                                    if (finalActive.toUri().getPath().contains("org/openide/loaders/OpenSupport.java")) {
2105:                                //                                        Exceptions.printStackTrace(t);
2106:                                //                                    }
2107:                                //                                }
2108:                                //                            }
2109:                                //                        };
2110:                                //                        f.run(jc.todo, types);
2111:                                //                        dumpClasses (listener.getEnteredTypes(), fileManager,
2112:                                //                                rootFo.getURL().toExternalForm(), dirtyFiles,
2113:                                //                                com.sun.tools.javac.code.Types.instance(jt.getContext()),
2114:                                //                                com.sun.tools.javac.util.Name.Table.instance(jt.getContext()));
2115:                                //                        if (listener.lowMemory.getAndSet(false)) {
2116:                                //                            jt.finish();
2117:                                //                            jt = null;
2118:                                //                            listener.cleanDiagnostics();
2119:                                //                            trees = null;
2120:                                //                            types = null;
2121:                                //                            if (state == 1) {
2122:                                //                                if (isBigFile) {
2123:                                //                                    break;
2124:                                //                                } else {
2125:                                //                                    bigFiles.add(active);
2126:                                //                                    active = null;
2127:                                //                                    state = 0;
2128:                                //                                }
2129:                                //                            } else {
2130:                                //                                state = 1;
2131:                                //                            }
2132:                                //                            System.gc();
2133:                                //                            continue;
2134:                                //                        }
2135:                                if (trees != null) {
2136:                                    ClassIndexImpl uqImpl = ClassIndexManager
2137:                                            .get(language).createUsagesQuery(
2138:                                                    root, true);
2139:                                    assert uqImpl != null;
2140:                                    SourceAnalyser sa = uqImpl
2141:                                            .getSourceAnalyser();
2142:                                    if (sa != null) {
2143:                                        sa.analyse(language, trees, jt,/* ClasspathInfoAccessor.INSTANCE.getFileManager(cpInfo),*/
2144:                                                active);
2145:                                    }
2146:                                }
2147:                                if (!listener.errors.isEmpty()) {
2148:                                    //Log.instance(jt.getContext()).nerrors = 0;
2149:                                    listener.cleanDiagnostics();
2150:                                }
2151:                                active = null;
2152:                                state = 0;
2153:                            } catch (Exception a) {
2154:                                //coupling error
2155:                                //TODO: check if the source sig file ~ the source java file:
2156:                                //couplingAbort(a, active);
2157:                                if (jt != null) {
2158:                                    jt.finish();
2159:                                }
2160:                                jt = null;
2161:                                listener.cleanDiagnostics();
2162:                                active = null;
2163:                                state = 0;
2164:                            } catch (Throwable t) {
2165:                                if (t instanceof  ThreadDeath) {
2166:                                    throw (ThreadDeath) t;
2167:                                } else {
2168:                                    if (jt != null) {
2169:                                        jt.finish();
2170:                                    }
2171:                                    String activeURI;
2172:                                    if (active != null) {
2173:                                        activeURI = active.getNameExt();
2174:                                    } else {
2175:                                        activeURI = "unknown";
2176:                                    }
2177:                                    jt = null;
2178:                                    active = null;
2179:                                    listener.cleanDiagnostics();
2180:                                    //if (!(t instanceof Abort)) { // a javac Throwable                                
2181:                                    final ClassPath bootPath = cpInfo
2182:                                            .getClassPath(ClasspathInfo.PathKind.BOOT);
2183:                                    final ClassPath classPath = cpInfo
2184:                                            .getClassPath(ClasspathInfo.PathKind.COMPILE);
2185:                                    final ClassPath sourcePath = cpInfo
2186:                                            .getClassPath(ClasspathInfo.PathKind.SOURCE);
2187:                                    t = Exceptions
2188:                                            .attachMessage(
2189:                                                    t,
2190:                                                    String
2191:                                                            .format(
2192:                                                                    "Root: %s File: %s Bootpath: %s Classpath: %s Sourcepath: %s",
2193:                                                                    FileUtil
2194:                                                                            .getFileDisplayName(rootFo),
2195:                                                                    activeURI
2196:                                                                            .toString(),
2197:                                                                    bootPath == null ? null
2198:                                                                            : bootPath
2199:                                                                                    .toString(),
2200:                                                                    classPath == null ? null
2201:                                                                            : classPath
2202:                                                                                    .toString(),
2203:                                                                    sourcePath == null ? null
2204:                                                                            : sourcePath
2205:                                                                                    .toString()));
2206:                                    Exceptions.printStackTrace(t);
2207:                                    //}
2208:                                }
2209:                            }
2210:                        }
2211:                        if (state == 1) {
2212:                            LOGGER
2213:                                    .warning("Not enough memory to compile folder: "
2214:                                            + FileUtil
2215:                                                    .getFileDisplayName(rootFo)); // NOI18N
2216:                        }
2217:                    } finally {
2218:                        if (jt != null) {
2219:                            jt.finish();
2220:                        }
2221:                    }
2222:                } finally {
2223:                    clearIndexerParserTasks();
2224:                    LowMemoryNotifier.getDefault().removeLowMemoryListener(
2225:                            listener);
2226:                }
2227:            }
2228:
2229:            private static Set<String> parseSet(String propertyName,
2230:                    String defaultValue) {
2231:                StringTokenizer st = new StringTokenizer(System.getProperty(
2232:                        propertyName, defaultValue), " \t\n\r\f,-:+!");
2233:                Set<String> result = new HashSet<String>();
2234:                while (st.hasMoreTokens()) {
2235:                    result.add(st.nextToken());
2236:                }
2237:                return result;
2238:            }
2239:
2240:            private static ClassPath.Entry getClassPathEntry(
2241:                    final ClassPath cp, final URL root) {
2242:                assert cp != null;
2243:                assert root != null;
2244:                for (ClassPath.Entry e : cp.entries()) {
2245:                    if (root.equals(e.getURL())) {
2246:                        return e;
2247:                    }
2248:                }
2249:                return null;
2250:            }
2251:
2252:            private class FilterListener implements  ChangeListener {
2253:
2254:                public void stateChanged(ChangeEvent event) {
2255:                    //            Object source = event.getSource();
2256:                    //            if (source instanceof JavaFileFilterImplementation) {
2257:                    //                List<URL> dirtyRoots = new LinkedList<URL> ();
2258:                    //                synchronized (filters) {
2259:                    //                    for (Map.Entry<URL,JavaFileFilterImplementation> e : filters.entrySet()) {
2260:                    //                        if (e.getValue() == source) {
2261:                    //                            dirtyRoots.add(e.getKey());
2262:                    //                        }
2263:                    //                    }
2264:                    //                }
2265:                    //                submit(Work.filterChange(dirtyRoots));
2266:                    //            }
2267:                }
2268:            }
2269:
2270:            public static synchronized RepositoryUpdater getDefault() {
2271:                if (instance == null) {
2272:                    instance = new RepositoryUpdater();
2273:                }
2274:                return instance;
2275:            }
2276:
2277:            // BEGIN TOR MODIFICATIONS
2278:            // There could be multiple indexers (for different languages) that want
2279:            // to index a given file. I will iterate over the indexers and let each
2280:            // indexer have a chance to index every file. To do this I compute
2281:            // a list of indexers in advance - and provide a place where we can
2282:            // cache the parser tasks such that only one is created per indexer.
2283:
2284:            private static List<IndexerEntry> indexers;
2285:
2286:            private static List<IndexerEntry> getIndexers() {
2287:                if (indexers == null) {
2288:                    indexers = new ArrayList<IndexerEntry>();
2289:                    for (Language language : LanguageRegistry.getInstance()) {
2290:                        Indexer indexer = language.getIndexer();
2291:                        if (indexer != null) {
2292:                            IndexerEntry entry = new IndexerEntry(language,
2293:                                    indexer);
2294:                            indexers.add(entry);
2295:                        }
2296:                    }
2297:                }
2298:
2299:                return indexers;
2300:            }
2301:
2302:            private static void clearIndexerParserTasks() {
2303:                for (IndexerEntry entry : getIndexers()) {
2304:                    entry.setParserTask(null);
2305:                }
2306:            }
2307:
2308:            private static class IndexerEntry {
2309:                private Language language;
2310:                private Indexer indexer;
2311:                private ParserTaskImpl task;
2312:
2313:                IndexerEntry(Language language, Indexer indexer) {
2314:                    this .language = language;
2315:                    this .indexer = indexer;
2316:                }
2317:
2318:                Indexer getIndexer() {
2319:                    return indexer;
2320:                }
2321:
2322:                Language getLanguage() {
2323:                    return language;
2324:                }
2325:
2326:                ParserTaskImpl getParserTask() {
2327:                    return task;
2328:                }
2329:
2330:                void setParserTask(ParserTaskImpl task) {
2331:                    this .task = task;
2332:                }
2333:            }
2334:
2335:            // END TOR MODIFICATIONS
2336:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.