| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| 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 <code>Source</code> |
| * objects, which are created in the process of compiling other |
| * <code>Source</code> objects. For example, when compiling an MXML |
| * document, which includes data binding expressions, we create a new |
| * <code>Source</code> for the <code>WatcherSetupUtil</code> class. |
| * |
| * @author Clement Wong |
| */ |
| public final class ResourceContainer |
| { |
| public ResourceContainer() |
| { |
| name2source = new LinkedHashMap<String, Source>(); |
| qname2source = new QNameMap<Source>(); |
| } |
| |
| private Map<String, Source> name2source; |
| private QNameMap<Source> 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<Source> 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<String, Source> sources() |
| { |
| Map result = new HashMap<String, Source>(qname2source.size()); |
| |
| for (Map.Entry<QName, Source> entry : qname2source.entrySet()) |
| { |
| result.put(entry.getKey().toString(), entry.getValue()); |
| } |
| |
| return result; |
| } |
| |
| public void setApplicationCache(ApplicationCache applicationCache) |
| { |
| this.applicationCache = applicationCache; |
| } |
| } |