////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
}