//////////////////////////////////////////////////////////////////////////////// // // ADOBE SYSTEMS INCORPORATED // Copyright 2005-2007 Adobe Systems Incorporated // All Rights Reserved. // // NOTICE: Adobe permits you to use, modify, and distribute this file // in accordance with the terms of the license agreement accompanying it. // //////////////////////////////////////////////////////////////////////////////// package flex2.compiler; import flex2.compiler.util.QName; import flex2.compiler.util.QNameMap; import flex2.tools.oem.ApplicationCache; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; /** * This class acts as a container for extra Source * objects, which are created in the process of compiling other * Source objects. For example, when compiling an MXML * document, which includes data binding expressions, we create a new * Source for the WatcherSetupUtil class. * * @author Clement Wong */ public final class ResourceContainer { public ResourceContainer() { name2source = new LinkedHashMap(); qname2source = new QNameMap(); } private Map name2source; private QNameMap qname2source; private ApplicationCache applicationCache; public Source addResource(Source s) { Source old = name2source.get(s.getName()); CompilationUnit u = old != null ? old.getCompilationUnit() : null; if (u == null || (u != null && !u.isDone()) || (old.getLastModified() != s.getLastModified()) || old.isUpdated(s)) { s.setOwner(this); name2source.put(s.getName(), s); return s; } else // if (u != null && u.isDone()) { return old.copy(); } } public Source findSource(String name) { if (applicationCache != null) { Source cachedSource = applicationCache.getSource(name); if ((cachedSource != null) && !cachedSource.isUpdated()) { CompilationUnit cachedCompilationUnit = cachedSource.getCompilationUnit(); if ((cachedCompilationUnit != null) && cachedCompilationUnit.hasTypeInfo) { Source source = cachedSource.copy(); cachedSource.reused(); name2source.put(name, source); return source; } } } return checkSource(name2source.get(name)); } Source findSource(String namespaceURI, String localPart) { assert localPart.indexOf('.') == -1 && localPart.indexOf('/') == -1 && localPart.indexOf(':') == -1 : "findSource(" + namespaceURI + "," + localPart + ") has bad localPart"; if (applicationCache != null) { String className = CompilerAPI.constructClassName(namespaceURI, localPart); Source cachedSource = applicationCache.getSource(className); if ((cachedSource != null) && !cachedSource.isUpdated()) { CompilationUnit cachedCompilationUnit = cachedSource.getCompilationUnit(); if ((cachedCompilationUnit != null) && cachedCompilationUnit.hasTypeInfo // If isDone is false, then cachedSource.copy() below will just bail, and return null && cachedCompilationUnit.isDone()) { Source source = cachedSource.copy(); cachedSource.reused(); name2source.put(source.getName(), source); qname2source.put(namespaceURI, localPart, source); return source; } } } return checkSource(qname2source.get(namespaceURI, localPart)); } private Source checkSource(Source s) { CompilationUnit u = s != null ? s.getCompilationUnit() : null; if ((u != null && !u.isDone()) || (s != null && s.isUpdated())) { // s.removeCompilationUnit(); } else if (u != null) { s = s.copy(); assert s != null; } return s; } public void refresh() { qname2source.clear(); for (Iterator i = name2source.values().iterator(); i.hasNext();) { Source s = i.next(); CompilationUnit u = s.getCompilationUnit(); if (u != null) { for (int j = 0, size = u.topLevelDefinitions.size(); j < size; j++) { QName qName = u.topLevelDefinitions.get(j); qname2source.put(qName, s); } } } } public Map sources() { Map result = new HashMap(qname2source.size()); for (Map.Entry entry : qname2source.entrySet()) { result.put(entry.getKey().toString(), entry.getValue()); } return result; } public void setApplicationCache(ApplicationCache applicationCache) { this.applicationCache = applicationCache; } }