| /* |
| * |
| * 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 org.apache.flex.compiler.internal.projects; |
| |
| import static com.google.common.collect.Lists.transform; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.commons.io.FileUtils; |
| |
| import org.apache.flex.abc.semantics.Name; |
| import org.apache.flex.compiler.asdoc.IASDocBundleDelegate; |
| import org.apache.flex.compiler.common.DependencyTypeSet; |
| import org.apache.flex.compiler.common.XMLName; |
| import org.apache.flex.compiler.config.Configuration; |
| import org.apache.flex.compiler.config.RSLSettings; |
| import org.apache.flex.compiler.constants.IASLanguageConstants; |
| import org.apache.flex.compiler.constants.IMetaAttributeConstants; |
| import org.apache.flex.compiler.css.ICSSManager; |
| import org.apache.flex.compiler.css.ICSSRule; |
| import org.apache.flex.compiler.definitions.IClassDefinition; |
| import org.apache.flex.compiler.definitions.IDefinition; |
| import org.apache.flex.compiler.definitions.IEffectDefinition; |
| import org.apache.flex.compiler.definitions.IEventDefinition; |
| import org.apache.flex.compiler.definitions.IFunctionDefinition; |
| import org.apache.flex.compiler.definitions.IGetterDefinition; |
| import org.apache.flex.compiler.definitions.INamespaceDefinition; |
| import org.apache.flex.compiler.definitions.IScopedDefinition; |
| import org.apache.flex.compiler.definitions.ISetterDefinition; |
| import org.apache.flex.compiler.definitions.IStyleDefinition; |
| import org.apache.flex.compiler.definitions.ITypeDefinition; |
| import org.apache.flex.compiler.definitions.IVariableDefinition; |
| import org.apache.flex.compiler.definitions.metadata.IMetaTag; |
| import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute; |
| import org.apache.flex.compiler.definitions.references.INamespaceReference; |
| import org.apache.flex.compiler.definitions.references.IResolvedQualifiersReference; |
| import org.apache.flex.compiler.definitions.references.ReferenceFactory; |
| import org.apache.flex.compiler.exceptions.LibraryCircularDependencyException; |
| import org.apache.flex.compiler.filespecs.IFileSpecification; |
| import org.apache.flex.compiler.internal.as.codegen.BindableHelper; |
| import org.apache.flex.compiler.internal.css.CSSManager; |
| import org.apache.flex.compiler.internal.css.codegen.CSSCompilationSession; |
| import org.apache.flex.compiler.internal.definitions.ClassDefinition; |
| import org.apache.flex.compiler.internal.definitions.FunctionDefinition; |
| import org.apache.flex.compiler.internal.definitions.NamespaceDefinition; |
| import org.apache.flex.compiler.internal.definitions.PackageDefinition; |
| import org.apache.flex.compiler.internal.mxml.MXMLDialect; |
| import org.apache.flex.compiler.internal.mxml.MXMLManifestManager; |
| import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping; |
| import org.apache.flex.compiler.internal.projects.DependencyGraph.Edge; |
| import org.apache.flex.compiler.internal.scopes.ASProjectScope; |
| import org.apache.flex.compiler.internal.scopes.ASScope; |
| import org.apache.flex.compiler.internal.scopes.PackageScope; |
| import org.apache.flex.compiler.internal.targets.AppSWFTarget; |
| import org.apache.flex.compiler.internal.targets.FlexAppSWFTarget; |
| import org.apache.flex.compiler.internal.targets.SWCTarget; |
| import org.apache.flex.compiler.internal.tree.mxml.MXMLImplicitImportNode; |
| import org.apache.flex.compiler.internal.workspaces.Workspace; |
| import org.apache.flex.compiler.mxml.IMXMLLanguageConstants; |
| import org.apache.flex.compiler.mxml.IMXMLManifestManager; |
| import org.apache.flex.compiler.mxml.IMXMLNamespaceMapping; |
| import org.apache.flex.compiler.projects.IFlexProject; |
| import org.apache.flex.compiler.scopes.IDefinitionSet; |
| import org.apache.flex.compiler.targets.ISWCTarget; |
| import org.apache.flex.compiler.targets.ISWFTarget; |
| import org.apache.flex.compiler.targets.ITargetProgressMonitor; |
| import org.apache.flex.compiler.targets.ITargetSettings; |
| import org.apache.flex.compiler.tree.ASTNodeID; |
| import org.apache.flex.compiler.tree.as.IASNode; |
| import org.apache.flex.compiler.tree.as.IImportNode; |
| import org.apache.flex.compiler.units.ICompilationUnit; |
| import org.apache.flex.compiler.units.requests.IOutgoingDependenciesRequestResult; |
| import org.apache.flex.compiler.units.requests.IRequest; |
| import org.apache.flex.compiler.workspaces.IWorkspace; |
| import org.apache.flex.swc.ISWC; |
| import com.google.common.collect.ImmutableList; |
| |
| /** |
| * {@code FlexProject} extends {@code ASProject} to add support for compiling |
| * .mxml, .css, and .properties files. |
| */ |
| public class FlexProject extends ASProject implements IFlexProject |
| { |
| // TODO Remove the redundant fooClass (a qname String) field |
| // when we have a fooClassName (an AET Name) field. We can always |
| // derive the qname from the AET name. |
| |
| /** |
| * Constructor |
| * |
| * @param workspace The {@code Workspace} containing this project. |
| * @param asDocBundleDelegate {@link IASDocBundleDelegate} the new project will use to find |
| * ASDoc comments for definitions from SWCs. |
| */ |
| public FlexProject(Workspace workspace, IASDocBundleDelegate asDocBundleDelegate) |
| { |
| super(workspace, true, asDocBundleDelegate); // the "true" here forces the opening of the AS3 namespace. |
| |
| getSourceCompilationUnitFactory().addHandler(MXMLSourceFileHandler.INSTANCE); |
| getSourceCompilationUnitFactory().addHandler(ResourceBundleSourceFileHandler.INSTANCE); |
| namespaceMappings = new MXMLNamespaceMapping[0]; |
| |
| implicitImportsForMXML = new String[0]; |
| implicitImportNodesForMXML = new ArrayList<IImportNode>(); |
| cssManager = new CSSManager(this); |
| localeDependentPaths = new HashMap<String, String>(); |
| locales = Collections.unmodifiableCollection(Collections.<String>emptySet()); |
| } |
| |
| /** |
| * Constructor |
| * |
| * @param workspace The {@code Workspace} containing this project. |
| */ |
| public FlexProject(Workspace workspace) |
| { |
| this(workspace, IASDocBundleDelegate.NIL_DELEGATE); |
| } |
| |
| private final ICSSManager cssManager; |
| |
| private Collection<String> locales; |
| |
| /** |
| * Maps for the locale dependent paths for the project. For each entry, |
| * the key is the path of a locale dependent path (can only be source path |
| * or library path entry) and the value is the locale it depends on. |
| */ |
| private final Map<String, String> localeDependentPaths; |
| |
| // The externally-visible fully-qualified ActionScript type name |
| // for an MXML <Component> tag. Currently this is "mx.core.IFactory". |
| private String componentTagType; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that corresponds to a <State> tag. |
| * Currently this is "mx.states.State". |
| */ |
| private String stateClass; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * for a component with a <code>currentState</code> property. |
| * Currently this is "mx.core.IStateClient". |
| */ |
| private String stateClientInterface; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that is used to implement a state-dependent instance |
| * such as <s:Button includeIn="s1">. |
| * This class must implement mx.states.IOverride. |
| * Currently this is "mx.states.AddItems". |
| */ |
| private String instanceOverrideClass; |
| |
| /** |
| * The AET Name for instanceOverrideClass. |
| */ |
| private Name instanceOverrideClassName; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that is used to implement a state-dependent property |
| * such as label.s1="OK". |
| * This class must implement mx.states.IOverride. |
| * Currently this is "mx.states.SetProperty". |
| */ |
| private String propertyOverrideClass; |
| |
| /** |
| * The AET Name for propertyOverrideClass. |
| */ |
| private Name propertyOverrideClassName; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that is used to implement a state-dependent style |
| * such as color.s1="#FF0000". |
| * This class must implement mx.states.IOverride. |
| * Currently this is "mx.states.SetStyle". |
| */ |
| private String styleOverrideClass; |
| |
| /** |
| * The AET Name for styleOverrideClass. |
| */ |
| private Name styleOverrideClassName; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that is used to implement a state-dependent event handler |
| * such as click.s1="doit()". |
| * This class must implement mx.states.IOverride. |
| * Currently this is "mx.states.SetEventHandler". |
| */ |
| private String eventOverrideClass; |
| |
| /** |
| * The AET Name for eventOverrideClass. |
| */ |
| private Name eventOverrideClassName; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * that represents a deferred instance. |
| * Currently this is "mx.core.IDeferredInstance". |
| */ |
| private String deferredInstanceInterface; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * that represents a transient deferred instance. |
| * Currently this is "mx.core.ITransientDeferredInstance". |
| */ |
| private String transientDeferredInstanceInterface; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that creates an IDeferredInstance from a class. |
| * Currently this is "mx.core.DeferredInstanceFromClass". |
| */ |
| private String deferredInstanceFromClassClass; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that creates an IDeferredInstance instance from a function. |
| * Currently this is "mx.core.DeferredInstanceFromFunction". |
| */ |
| private String deferredInstanceFromFunctionClass; |
| |
| private Name deferredInstanceFromFunctionName; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * that represents a factory for creating instances. |
| * Currently this is "mx.core.Factory". |
| */ |
| private String factoryInterface; |
| |
| /** |
| * The fully-qualified name of the proxy base class |
| * that causes the compiler to generate getProperty/setProperty calls. |
| * Currently this is "flash.utils.Proxy". |
| */ |
| private String proxyBaseClass; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that creates an IFactory from a class. |
| * Currently this is "mx.core.ClassFactory". |
| */ |
| private String classFactoryClass; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * representing non-visual elements whose |
| * <code>initialized()</code> method should be called. |
| * Currently this is "mx.core.IMXMLObject". |
| */ |
| private String mxmlObjectInterface; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * for MX containers. |
| * Currently this is "mx.core.IContainer". |
| */ |
| private String containerInterface; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * for visual element containers. |
| * Currently this is "mx.core.IVisualElementContainer". |
| */ |
| private String visualElementContainerInterface; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that represents a resource bundle. |
| * Currently this is "mx.resources.ResourceBundle". |
| */ |
| private String resourceBundleClass; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that represents the resource manager. |
| * Currently this is "mx.resources.ResourceManager". |
| */ |
| private String resourceManagerClass; |
| |
| /** |
| * The fully-qualified name of the module base class |
| * that represents a resource module instance. |
| * Currently this is "flex.compiler.support.ResourceModuleBase". |
| */ |
| private String resourceModuleBaseClass; |
| |
| /** |
| * The AET Name for resourceManagerClass. |
| */ |
| private Name resourceManagerClassName; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * that manages databinding. |
| * Currently this is "mx.binding.BindingManager". |
| */ |
| private String bindingManagerClass; |
| |
| /** |
| * The AET Name for bindingManagerClass. |
| */ |
| private Name bindingManagerClassName; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * for internal Binding object |
| * Currently this is "mx.binding.Binding". |
| */ |
| private String bindingClass; |
| |
| /** |
| * The AET Name for bindingClass |
| */ |
| private Name bindingClassName; |
| |
| /** |
| * List of RSL configured in this application. |
| */ |
| private List<RSLSettings> rslSettingsList; |
| |
| /** |
| * A list of theme files applicable to this project. |
| */ |
| private ImmutableList<IFileSpecification> themeFiles = ImmutableList.of(); |
| |
| private String propertyWatcherClass; |
| private String staticPropertyWatcherClass; |
| private Name propertyWatcherClassName; |
| private Name staticPropertyWatcherClassName; |
| private String functionReturnWatcherClass; |
| private Name functionReturnWatcherClassName; |
| private String objectProxyClass; |
| private String xmlWatcherClass; |
| private Name xmlWatcherClassName; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * for MX component descriptors. |
| * Currently this is "mx.core.UIComponentDescriptor". |
| */ |
| private String uiComponentDescriptorClass; |
| |
| /** |
| * The AET Name for uiComponentDescriptorClass. |
| */ |
| private Name uiComponentDescriptorClassName; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * implementing an <fx:Model>. |
| * Currently this is "mx.utils.ObjectProxy". |
| */ |
| private String modelClass; |
| |
| /** |
| * The AET Name for modelClass. |
| */ |
| private Name modelClassName; |
| |
| /** |
| * The fully-qualified name of the runtime class |
| * implementing a CSS rule. |
| * Currently this is "mx.styles.CSSStyleDeclaration". |
| */ |
| private String cssStyleDeclarationClass; |
| |
| /** |
| * The AET Name for cssStyleDeclarationClass; |
| */ |
| private Name cssStyleDeclarationClassName; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * for classes supporting a moduleFactory property. |
| * Currently this is "mx.core.IFlexModule". |
| */ |
| private String flexModuleInterface; |
| |
| /** |
| * The fully-qualified name of the runtime interface |
| * for UIComponents that support deferred instantiation. |
| * Currently this is "mx.core.IDeferredInstantiationUIComponent". |
| */ |
| private String deferredInstantiationUIComponentInterface; |
| |
| /** |
| * A map of color names to RGB color values. |
| */ |
| private Map<String, Integer> namedColors; |
| |
| // A list of imports, such as "flash.display.*", that is automatically |
| // imported by every MXML file. |
| private String[] implicitImportsForMXML; |
| |
| private List<IImportNode> implicitImportNodesForMXML; |
| |
| // Keeps track of MXML-namespace-URI-to-manifest-file options such as |
| // --namespace=http://foo.whatever.com,mymanifest.xml |
| private IMXMLNamespaceMapping[] namespaceMappings; |
| |
| // This object maintains MXML-tag-to-ActionScript-class mapping info |
| // aggregated from the <component> tags in the catalog.xml files |
| // inside the SWCs on the project's library path and from the <component> |
| // tags in any manifest files associated with XML namespaces. |
| private IMXMLManifestManager manifestManager; |
| |
| /** |
| * The fully qualified name of the XMLUtil class. |
| * Currently this is mx.utils.XMLUtil. |
| */ |
| private String xmlUtilClass; |
| |
| /** |
| * The AET Name for xmlUtilClass. |
| */ |
| private Name xmlUtilClassName; |
| |
| /** |
| * An absolute path to the services-config.xml file. Will be null |
| * if the -services option is not specified. |
| */ |
| private String servicesXMLPath; |
| |
| /** |
| * The context root used with servicesXMLPath. |
| */ |
| private String servicesContextRoot; |
| |
| /** |
| * QName of the class definition for {@code <s:WebService>} tag. |
| */ |
| private String webServiceQName; |
| |
| /** |
| * QName of the class definition for {@code <s:operation>} child tag of a |
| * {@code <s:WebService>} tag. |
| */ |
| private String webServiceOperationQName; |
| |
| /** |
| * QName of the class definition for {@code <s:RemoteObject>} tag. |
| */ |
| private String remoteObjectQName; |
| |
| /** |
| * QName of the class definition for {@code <s:method>} child tag of a |
| * {@code <s:RemoteObject>} tag. |
| */ |
| private String remoteObjectMethodQName; |
| |
| // |
| // Backing variables for new configuration setter API. |
| // |
| private String actionScriptFileEncoding = "utf-8"; |
| private Map<File, List<String>> extensions; |
| private boolean isFlex = false; |
| private boolean strictXML = false; |
| |
| /** |
| * QName of the class definition for {@code <s:HTTPService>} tag. |
| */ |
| private String httpServiceQName; |
| |
| /** |
| * QName of the class definition for {@code <fx:DesignLayer>} tag. |
| */ |
| private String designLayerQName; |
| |
| /** |
| * QName of the class definition for {@code <mx:Repeater>} tag. |
| */ |
| private String repeaterQName; |
| |
| /** |
| * target settings |
| */ |
| private ITargetSettings targetSettings; |
| |
| /** |
| * target settings |
| */ |
| public ITargetSettings getTargetSettings() |
| { |
| return targetSettings; |
| } |
| |
| /** |
| * target settings |
| */ |
| public void setTargetSettings(ITargetSettings value) |
| { |
| targetSettings = value; |
| } |
| |
| private ISWFTarget target; |
| |
| public ISWFTarget getSWFTarget() |
| { |
| return target; |
| } |
| |
| @Override |
| public ISWFTarget createSWFTarget(ITargetSettings targetSettings, ITargetProgressMonitor progressMonitor) throws InterruptedException |
| { |
| this.targetSettings = targetSettings; |
| |
| if (isFlex()) |
| { |
| String rootClassName = targetSettings.getRootClassName(); |
| target = new FlexAppSWFTarget(ReferenceFactory.packageQualifiedReference( |
| getWorkspace(), rootClassName, true), |
| this, targetSettings, progressMonitor); |
| } |
| else |
| { |
| target = new AppSWFTarget(this, targetSettings, progressMonitor); |
| } |
| |
| return target; |
| } |
| |
| @Override |
| public ISWCTarget createSWCTarget(ITargetSettings targetSettings, ITargetProgressMonitor progressMonitor) throws InterruptedException |
| { |
| this.targetSettings = targetSettings; |
| |
| return new SWCTarget(this, targetSettings, progressMonitor); |
| } |
| |
| /** |
| * Convert a color to an integer value. |
| * |
| * @param colorValue may be a named color, or a String in |
| * any format supported by Integer.decode(). May not be null. |
| * @return the color as an integer. |
| * @throws NumberFormatException if the value is not a named color and is not |
| * properly formatted for Integer.decode(). |
| * @throws NullPointerException is colorValue is null. |
| */ |
| public int getColorAsInt(String colorValue) throws NumberFormatException |
| { |
| if (colorValue == null) |
| throw new NullPointerException("colorValue may not be null"); |
| |
| if (namedColors != null) |
| { |
| Integer value = namedColors.get(colorValue); |
| if (value != null) |
| return value.intValue(); |
| } |
| |
| return Integer.decode(colorValue).intValue(); |
| } |
| |
| /** |
| * Gets the fully-qualified type name corresponding to a <Component> tag. |
| * |
| * @return The type name as a String. |
| */ |
| public String getComponentTagType() |
| { |
| return componentTagType; |
| } |
| |
| /** |
| * Sets the fully-qualified type name corresponding to a <Component> tag. |
| * |
| * @param componentTagType The type name as a String. |
| */ |
| public void setComponentTagType(String componentTagType) |
| { |
| this.componentTagType = componentTagType; |
| } |
| |
| public String getStateClass() |
| { |
| return stateClass; |
| } |
| |
| public void setStateClass(String stateClass) |
| { |
| this.stateClass = stateClass; |
| } |
| |
| public String getStateClientInterface() |
| { |
| return stateClientInterface; |
| } |
| |
| public void setStateClientInterface(String stateClientInterface) |
| { |
| this.stateClientInterface = stateClientInterface; |
| } |
| |
| public String getInstanceOverrideClass() |
| { |
| return instanceOverrideClass; |
| } |
| |
| public Name getInstanceOverrideClassName() |
| { |
| return instanceOverrideClassName; |
| } |
| |
| public void setInstanceOverrideClass(String instanceOverrideClass) |
| { |
| this.instanceOverrideClass = instanceOverrideClass; |
| instanceOverrideClassName = getMNameForQName(instanceOverrideClass); |
| } |
| |
| public String getPropertyOverrideClass() |
| { |
| return propertyOverrideClass; |
| } |
| |
| public Name getPropertyOverrideClassName() |
| { |
| return propertyOverrideClassName; |
| } |
| |
| public void setPropertyOverrideClass(String propertyOverrideClass) |
| { |
| this.propertyOverrideClass = propertyOverrideClass; |
| propertyOverrideClassName = getMNameForQName(propertyOverrideClass); |
| } |
| |
| public String getStyleOverrideClass() |
| { |
| return styleOverrideClass; |
| } |
| |
| public Name getStyleOverrideClassName() |
| { |
| return styleOverrideClassName; |
| } |
| |
| public void setStyleOverrideClass(String styleOverrideClass) |
| { |
| this.styleOverrideClass = styleOverrideClass; |
| styleOverrideClassName = getMNameForQName(styleOverrideClass); |
| } |
| |
| public String getEventOverrideClass() |
| { |
| return eventOverrideClass; |
| } |
| |
| public Name getEventOverrideClassName() |
| { |
| return eventOverrideClassName; |
| } |
| |
| public void setEventOverrideClass(String eventOverrideClass) |
| { |
| this.eventOverrideClass = eventOverrideClass; |
| eventOverrideClassName = getMNameForQName(eventOverrideClass); |
| } |
| |
| public String getDeferredInstanceInterface() |
| { |
| return deferredInstanceInterface; |
| } |
| |
| public void setDeferredInstanceInterface(String deferredInstanceInterface) |
| { |
| this.deferredInstanceInterface = deferredInstanceInterface; |
| } |
| |
| public String getTransientDeferredInstanceInterface() |
| { |
| return transientDeferredInstanceInterface; |
| } |
| |
| public void setTransientDeferredInstanceInterface(String transientDeferredInstanceInterface) |
| { |
| this.transientDeferredInstanceInterface = transientDeferredInstanceInterface; |
| } |
| |
| public String getDeferredInstanceFromClassClass() |
| { |
| return deferredInstanceFromClassClass; |
| } |
| |
| public void setDeferredInstanceFromClassClass(String deferredInstanceFromClassClass) |
| { |
| this.deferredInstanceFromClassClass = deferredInstanceFromClassClass; |
| } |
| |
| public String getDeferredInstanceFromFunctionClass() |
| { |
| return deferredInstanceFromFunctionClass; |
| } |
| |
| public Name getDeferredInstanceFromFunctionName() |
| { |
| return deferredInstanceFromFunctionName; |
| } |
| |
| public void setDeferredInstanceFromFunctionClass(String deferredInstanceFromFunctionClass) |
| { |
| this.deferredInstanceFromFunctionClass = deferredInstanceFromFunctionClass; |
| deferredInstanceFromFunctionName = getMNameForQName(deferredInstanceFromFunctionClass); |
| } |
| |
| public String getFactoryInterface() |
| { |
| return factoryInterface; |
| } |
| |
| public void setFactoryInterface(String factoryInterface) |
| { |
| this.factoryInterface = factoryInterface; |
| } |
| |
| public String getMXMLObjectInterface() |
| { |
| return mxmlObjectInterface; |
| } |
| |
| public void setMXMLObjectInterface(String mxmlObjectInterface) |
| { |
| this.mxmlObjectInterface = mxmlObjectInterface; |
| } |
| |
| public String getProxyBaseClass() |
| { |
| return proxyBaseClass; |
| } |
| |
| public void setProxyBaseClass(String proxyBaseClass) |
| { |
| this.proxyBaseClass = proxyBaseClass; |
| } |
| |
| public String getClassFactoryClass() |
| { |
| return classFactoryClass; |
| } |
| |
| public void setClassFactoryClass(String classFactoryClass) |
| { |
| this.classFactoryClass = classFactoryClass; |
| } |
| |
| public String getContainerInterface() |
| { |
| return containerInterface; |
| } |
| |
| public void setContainerInterface(String containerInterface) |
| { |
| this.containerInterface = containerInterface; |
| } |
| |
| public String getVisualElementContainerInterface() |
| { |
| return visualElementContainerInterface; |
| } |
| |
| public void setVisualElementContainerInterface(String visualElementContainerInterface) |
| { |
| this.visualElementContainerInterface = visualElementContainerInterface; |
| } |
| |
| public String getResourceBundleClass() |
| { |
| return resourceBundleClass; |
| } |
| |
| public void setResourceBundleClass(String resourceBundleClass) |
| { |
| this.resourceBundleClass = resourceBundleClass; |
| } |
| |
| public String getResourceManagerClass() |
| { |
| return resourceManagerClass; |
| } |
| |
| public Name getResourceManagerClassName() |
| { |
| return resourceManagerClassName; |
| } |
| |
| public void setResourceManagerClass(String resourceManagerClass) |
| { |
| this.resourceManagerClass = resourceManagerClass; |
| resourceManagerClassName = getMNameForQName(resourceManagerClass); |
| } |
| |
| public String getBindingManagerClass() |
| { |
| return bindingManagerClass; |
| } |
| |
| public Name getBindingManagerClassName() |
| { |
| return bindingManagerClassName; |
| } |
| |
| public String getResourceModuleBaseClass() |
| { |
| return resourceModuleBaseClass; |
| } |
| |
| public void setResourceModuleBaseClass(String resourceModuleBaseClass) |
| { |
| this.resourceModuleBaseClass = resourceModuleBaseClass; |
| } |
| |
| public void setBindingManagerClass(String bindingManagerClass) |
| { |
| this.bindingManagerClass = bindingManagerClass; |
| bindingManagerClassName = getMNameForQName(bindingManagerClass); |
| } |
| |
| public String getXMLUtilClass() |
| { |
| return xmlUtilClass; |
| } |
| |
| public Name getXMLUtilClassName() |
| { |
| return xmlUtilClassName; |
| } |
| |
| public void setXMLUtilClass(String xmlUtilClass) |
| { |
| this.xmlUtilClass = xmlUtilClass; |
| xmlUtilClassName = getMNameForQName(xmlUtilClass); |
| } |
| |
| /** |
| * Get the fully-qualified name of the runtime class |
| * for internal Binding object |
| * Currently this is "mx.binding.Binding". |
| */ |
| public String getBindingClass() |
| { |
| return bindingClass; |
| } |
| |
| /** |
| * Get the AET Name for bindingClass |
| * @see #getBindingClass |
| */ |
| public Name getBindingClassName() |
| { |
| assert bindingClassName != null; |
| return bindingClassName; |
| } |
| |
| public void setBindingClass(String bindingClass) |
| { |
| this.bindingClass = bindingClass; |
| this.bindingClassName = getMNameForQName(bindingClass); |
| } |
| |
| /** |
| * Get the fully-qualified name of the runtime class |
| * for internal PropertyWatcher object |
| * Currently this is "mx.binding.PropertyWatcher". |
| */ |
| public String getPropertyWatcherClass() |
| { |
| return propertyWatcherClass; |
| } |
| |
| public String getObjectProxyClass() |
| { |
| return objectProxyClass; |
| } |
| |
| public void setObjectProxyClass(String objectProxyClass) |
| { |
| this.objectProxyClass = objectProxyClass; |
| } |
| |
| /** |
| * Get the AET Name for propertyWatcherClass |
| * @see #getPropertyWatcherClass |
| */ |
| public Name getPropertyWatcherClassName() |
| { |
| assert propertyWatcherClassName != null; |
| return propertyWatcherClassName; |
| } |
| |
| public void setPropertyWatcherClass(String propertyWatcherClass) |
| { |
| this.propertyWatcherClass = propertyWatcherClass; |
| this.propertyWatcherClassName = getMNameForQName(propertyWatcherClass); |
| } |
| |
| /** |
| * Get the fully-qualified name of the runtime class |
| * for internal StaticPropertyWatcher object |
| * Currently this is "mx.binding.StaticPropertyWatcher". |
| */ |
| public String getStaticPropertyWatcherClass() |
| { |
| return staticPropertyWatcherClass; |
| } |
| |
| /** |
| * Get the AET Name for staticPropertyWatcherClass |
| * @see #getStaticPropertyWatcherClass |
| */ |
| public Name getStaticPropertyWatcherClassName() |
| { |
| assert staticPropertyWatcherClassName != null; |
| return staticPropertyWatcherClassName; |
| } |
| |
| public void setStaticPropertyWatcherClass(String staticPropertyWatcherClass) |
| { |
| this.staticPropertyWatcherClass = staticPropertyWatcherClass; |
| this.staticPropertyWatcherClassName = getMNameForQName(staticPropertyWatcherClass); |
| } |
| |
| public Name getXMLWatcherClassName() |
| { |
| return xmlWatcherClassName; |
| } |
| |
| public String getXMLWatcherClass() |
| { |
| return xmlWatcherClass; |
| } |
| |
| public void setXMLWatcherClass(String xmlWatcherClass) |
| { |
| this.xmlWatcherClass = xmlWatcherClass; |
| this.xmlWatcherClassName = getMNameForQName(xmlWatcherClass); |
| } |
| |
| /** |
| * Get the fully-qualified name of the runtime class |
| * for internal StaticPropertyWatcher object |
| * Currently this is "mx.binding.StaticPropertyWatcher". |
| */ |
| public String getFunctionReturnWatcherClass() |
| { |
| return functionReturnWatcherClass; |
| } |
| |
| /** |
| * Get the AET Name for staticPropertyWatcherClass |
| * @see #getStaticPropertyWatcherClass |
| */ |
| public Name getFunctionReturnWatcherClassName() |
| { |
| assert functionReturnWatcherClassName != null; |
| return functionReturnWatcherClassName; |
| } |
| |
| public void setFunctionReturnWatcherClass(String staticPropertyWatcherClass) |
| { |
| this.functionReturnWatcherClass = staticPropertyWatcherClass; |
| this.functionReturnWatcherClassName = getMNameForQName(staticPropertyWatcherClass); |
| } |
| |
| public String getUIComponentDescriptorClass() |
| { |
| return uiComponentDescriptorClass; |
| } |
| |
| public Name getUIComponentDescriptorClassName() |
| { |
| return uiComponentDescriptorClassName; |
| } |
| |
| public void setUIComponentDescriptorClass(String uiComponentDescriptorClass) |
| { |
| this.uiComponentDescriptorClass = uiComponentDescriptorClass; |
| uiComponentDescriptorClassName = getMNameForQName(uiComponentDescriptorClass); |
| } |
| |
| public String getModelClass() |
| { |
| return modelClass; |
| } |
| |
| public Name getModelClassName() |
| { |
| return modelClassName; |
| } |
| |
| public void setModelClass(String modelClass) |
| { |
| this.modelClass = modelClass; |
| modelClassName = getMNameForQName(modelClass); |
| } |
| |
| public String getCSSStyleDeclarationClass() |
| { |
| return cssStyleDeclarationClass; |
| } |
| |
| public Name getCSSStyleDeclarationClassName() |
| { |
| return cssStyleDeclarationClassName; |
| } |
| |
| public void setCSSStyleDeclarationClass(String cssStyleDeclarationClass) |
| { |
| this.cssStyleDeclarationClass = cssStyleDeclarationClass; |
| cssStyleDeclarationClassName = getMNameForQName(cssStyleDeclarationClass); |
| } |
| |
| public String getFlexModuleInterface() |
| { |
| return flexModuleInterface; |
| } |
| |
| public void setFlexModuleInterface(String flexModuleInterface) |
| { |
| this.flexModuleInterface = flexModuleInterface; |
| } |
| |
| public String getDeferredInstantiationUIComponentInterface() |
| { |
| return deferredInstantiationUIComponentInterface; |
| } |
| |
| public void setDeferredInstantiationUIComponentInterface(String deferredInstantiationUIComponentInterface) |
| { |
| this.deferredInstantiationUIComponentInterface = deferredInstantiationUIComponentInterface; |
| } |
| |
| public Integer getNamedColor(String colorName) |
| { |
| return namedColors != null ? namedColors.get(colorName) : null; |
| } |
| |
| public void setNamedColors(Map<String, Integer> namedColors) |
| { |
| this.namedColors = namedColors; |
| } |
| |
| /** |
| * Get a list of additional imports based on the MXML dialect being used. |
| * |
| * @param dialect - the dialect of the MXML language being compiled. |
| * @return An array of Strings such as <code>flash.display.*"</code>. |
| */ |
| private List<String>getMXMLVersionDependentImports(MXMLDialect dialect) { |
| |
| List<String> imports = new ArrayList<String>(); |
| |
| if (dialect.isEqualToOrAfter(MXMLDialect.MXML_2009)) |
| { |
| // add "mx.filters.*" and "spark.filters.*" |
| imports.add("mx.filters.*"); |
| imports.add("spark.filters.*"); |
| } |
| else |
| { |
| // add "flash.filters.*" |
| imports.add("flash.filters.*"); |
| } |
| |
| return imports; |
| } |
| |
| /** |
| * Gets the imports that are automatically imported into every MXML file. |
| * |
| * @param dialect - the dialect of the MXML language being compiled. |
| * @return An array of Strings such as <code>flash.display.*"</code>. |
| */ |
| public String[] getImplicitImportsForMXML(MXMLDialect dialect) |
| { |
| String[] additionalImports = getMXMLVersionDependentImports(dialect).toArray(new String[0]); |
| String[] imports = new String[implicitImportsForMXML.length + |
| additionalImports.length]; |
| |
| // append MXML version dependent imports to the standard imports. |
| System.arraycopy(implicitImportsForMXML, 0, imports, 0, implicitImportsForMXML.length); |
| System.arraycopy(additionalImports, 0, imports, implicitImportsForMXML.length, additionalImports.length); |
| |
| return imports; |
| } |
| |
| /** |
| * Gets a list of nodes representing the implicit imports, for CodeModel. |
| * |
| * @param dialect - the dialect of the MXML language being compiled. |
| * @return A list of {@code MXMLImplicitImportNode} objects. |
| */ |
| public List<IImportNode> getImplicitImportNodesForMXML(MXMLDialect dialect) |
| { |
| List<String> additionalImports = getMXMLVersionDependentImports(dialect); |
| List<IImportNode> importNodes = new ArrayList<IImportNode>(implicitImportNodesForMXML.size() + |
| additionalImports.size()); |
| |
| // append MXML version dependent imports to the standard imports. |
| importNodes.addAll(implicitImportNodesForMXML); |
| |
| for (String additionalImport : additionalImports) |
| { |
| importNodes.add(new MXMLImplicitImportNode(this, additionalImport)); |
| } |
| |
| return importNodes; |
| } |
| |
| /** |
| * Sets the imports that are automatically imported into every MXML file. |
| * |
| * @param implicitImportsForMXML An array of Strings such as |
| * <code>"flash.display.*"</code>. |
| */ |
| public void setImplicitImportsForMXML(String[] implicitImportsForMXML) |
| { |
| this.implicitImportsForMXML = implicitImportsForMXML; |
| |
| implicitImportNodesForMXML = new ArrayList<IImportNode>(implicitImportsForMXML.length); |
| for (String implicitImport : implicitImportsForMXML) |
| { |
| implicitImportNodesForMXML.add(new MXMLImplicitImportNode(this, implicitImport)); |
| } |
| } |
| |
| /** |
| * Gets the mappings from MXML namespace URI to manifest files, as specified |
| * by -namespace options. |
| * |
| * @return An array of {@code IMXMLNamespaceMapping} objects. |
| */ |
| @Override |
| public IMXMLNamespaceMapping[] getNamespaceMappings() |
| { |
| return namespaceMappings; |
| } |
| |
| /** |
| * Delete the current manifest manager. Next time it's used, it will be |
| * re-initialized. |
| */ |
| public void invalidateManifestManager() |
| { |
| manifestManager = null; |
| } |
| |
| /** |
| * Initialize and return {@link MXMLManifestManager} on demand. |
| * |
| * @return {@link MXMLManifestManager} |
| */ |
| private IMXMLManifestManager getMXMLManifestManager() |
| { |
| if (manifestManager == null) |
| manifestManager = new MXMLManifestManager(this); |
| return manifestManager; |
| } |
| |
| @Override |
| public String resolveXMLNameToQualifiedName(XMLName xmlName, MXMLDialect mxmlDialect) |
| { |
| String qname = getMXMLManifestManager().resolve(xmlName); |
| |
| if (qname == null) |
| { |
| // If the XML name wasn't found in the manifest manager, |
| // see if the URI has the form of package namespace. |
| // For example, <ns:Foo xmlns="*"> resolves to "Foo" |
| // and <ns:Foo xmlns="com.whatever.*" resolves to "com.whatever.Foo". |
| String shortName = xmlName.getName(); |
| String uri = xmlName.getXMLNamespace(); |
| String packageName = PackageDefinition.getQualifiedPackageNameFromNamespaceURI(uri); |
| if (packageName != null) |
| qname = packageName.length() == 0 ? shortName : packageName + "." + shortName; |
| } |
| |
| if (qname == null) |
| { |
| // If the XML name still hasn't resolved, check whether it is a <State> tag. |
| // If so, it maps to a special framework class (currently "mx.states.State"). |
| // For MXML 2009 and MXML 2012, recognize it in the |
| // "library://ns.adobe.com/flex/spark" namespace. |
| // For MXML 2006, recognize it in the "http://www.adobe.com/2006/mxml" namespace. |
| if (xmlName.getName().equals(IMXMLLanguageConstants.STATE)) |
| { |
| if ((mxmlDialect.isEqualToOrAfter(MXMLDialect.MXML_2009) && |
| xmlName.getXMLNamespace().equals("library://ns.adobe.com/flex/spark") || |
| mxmlDialect == MXMLDialect.MXML_2006 && |
| xmlName.getXMLNamespace().equals("http://www.adobe.com/2006/mxml"))) |
| { |
| qname = stateClass; |
| } |
| } |
| } |
| |
| if (qname == null) |
| { |
| // If the XML name still hasn't resolved, check whether it is a <Component> tag. |
| // If so, it maps to a special framework type (currently "mx.core.IFactory"). |
| XMLName componentTag = mxmlDialect.resolveComponent(); |
| if (xmlName.equals(componentTag)) |
| qname = componentTagType; |
| } |
| |
| return qname; |
| } |
| |
| @Override |
| public IDefinition resolveXMLNameToDefinition(XMLName xmlName, MXMLDialect mxmlDialect) |
| { |
| String qName = resolveXMLNameToQualifiedName(xmlName, mxmlDialect); |
| if (qName != null) |
| return resolveQNameToDefinition(qName); |
| else |
| return null; |
| } |
| |
| /** |
| * Searches the specified class, and its superclasses, for the definition of |
| * a specified property, event, or style. |
| * |
| * @param classDefinition The class on which the property, event, or style |
| * lookup should start. |
| * @param specifierName The name of the property, event, or style. |
| * @return An {@code IDefinition} object for the specifier, or |
| * <code>null</code> if the specified name doesn't resolve to a property, an |
| * event, or a style. |
| */ |
| public IDefinition resolveSpecifier(IClassDefinition classDefinition, String specifierName) |
| { |
| IDefinition definition = null; |
| |
| // From DeclarationHandler.invoke, the correct resolution |
| // order is: |
| // event |
| // property |
| // effect |
| // style |
| // dynamic property (if the class is dynamic) |
| |
| // Try to resolve the specifier as a event. |
| definition = resolveEvent(classDefinition, specifierName); |
| if (definition != null) |
| return definition; |
| |
| // Then try to resolve it as an property. |
| definition = resolveProperty(classDefinition, specifierName); |
| if (definition != null) |
| return definition; |
| |
| // Then try to resolve it as an effect. |
| definition = resolveEffect(classDefinition, specifierName); |
| if (definition != null) |
| return definition; |
| |
| // Then try to resolve it as an style. |
| definition = resolveStyle(classDefinition, specifierName); |
| if (definition != null) |
| return definition; |
| |
| // Finally try to resolve it as a dynamic property |
| |
| return null; |
| } |
| |
| /** |
| * Searches the specified class, and its superclasses, for a definition |
| * of a setter or variable with the specified name. |
| * |
| * @param classDefinition The class. |
| * @param propertyName The name of the property to search for. |
| * @return A setter definition or a variable definition. |
| */ |
| public IDefinition resolveProperty(IClassDefinition classDefinition, String propertyName) |
| { |
| Iterator<IClassDefinition> classIterator = classDefinition.classIterator(this, true); |
| while (classIterator.hasNext()) |
| { |
| IClassDefinition c = classIterator.next(); |
| |
| ASScope classScope = ((ClassDefinition)c).getContainedScope(); |
| IDefinitionSet definitionSet = classScope.getLocalDefinitionSetByName(propertyName); |
| if (definitionSet != null) |
| { |
| IDefinition winner = null; |
| |
| int n = definitionSet.getSize(); |
| for (int i = 0; i < n; i++) |
| { |
| IDefinition definition = definitionSet.getDefinition(i); |
| |
| // Look for vars and setters, but not getters. |
| // Remember that getters and setters implement IVariableDefinition! |
| if (definition instanceof IVariableDefinition && |
| !(definition instanceof IGetterDefinition)) |
| { |
| // TODO Add namespace logic. |
| // Can MXML set protected properties? |
| // Can MXML set mx_internal properties if you've done |
| // 'use namesapce mx_internal' in a <Script>? |
| winner = definition; |
| final INamespaceReference namespaceReference = definition.getNamespaceReference(); |
| final INamespaceDefinition thisNamespaceDef = namespaceReference.resolveNamespaceReference(this); |
| final boolean isBindable = ((NamespaceDefinition)thisNamespaceDef).getAETNamespace().getName().equals( |
| BindableHelper.bindableNamespaceDefinition.getAETNamespace().getName()); |
| // if we find a setter always take it, otherwise |
| // keep looking for a setter |
| if (winner instanceof ISetterDefinition && !isBindable) |
| break; |
| } |
| } |
| if (winner != null) |
| return winner; |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Searches the specified class, and its superclasses, for an event |
| * definition with the specified name. |
| * |
| * @param classDefinition The class. |
| * @param eventName The name of the event to search for. |
| * @return An event definition. |
| */ |
| public IEventDefinition resolveEvent(IClassDefinition classDefinition, String eventName) |
| { |
| Iterator<IClassDefinition> classIterator = classDefinition.classIterator(this, true); |
| while (classIterator.hasNext()) |
| { |
| IClassDefinition c = classIterator.next(); |
| IEventDefinition eventDefinition = c.getEventDefinition(getWorkspace(), eventName); |
| if (eventDefinition != null) |
| return eventDefinition; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Searches the specified class, and its superclasses, for a style |
| * definition with the specified name. |
| * |
| * @param classDefinition The class. |
| * @param styleName The name of the style to search for. |
| * @return A style definition. |
| */ |
| public IStyleDefinition resolveStyle(IClassDefinition classDefinition, String styleName) |
| { |
| Iterator<IClassDefinition> classIterator = classDefinition.classIterator(this, true); |
| |
| IWorkspace w = getWorkspace(); |
| while (classIterator.hasNext()) |
| { |
| IClassDefinition c = classIterator.next(); |
| IStyleDefinition styleDefinition = c.getStyleDefinition(w, styleName); |
| if (styleDefinition != null) |
| return styleDefinition; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Searches the specified class, and its superclasses, for an effect |
| * definition with the specified name. |
| * |
| * @param classDefinition The class. |
| * @param effectName The name of the effect to search for. |
| * @return An effect definition. |
| */ |
| public IEffectDefinition resolveEffect(IClassDefinition classDefinition, String effectName) |
| { |
| IWorkspace w = getWorkspace(); |
| |
| Iterator<IClassDefinition> classIterator = classDefinition.classIterator(this, true); |
| while (classIterator.hasNext()) |
| { |
| IClassDefinition c = classIterator.next(); |
| IEffectDefinition effectDefinition = c.getEffectDefinition(w, effectName); |
| if (effectDefinition != null) |
| return effectDefinition; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Uses the manifest information to find all the MXML tags that map to a |
| * specified fully-qualified ActionScript classname, such as as |
| * <code>"spark.controls.Button"</code> |
| * |
| * @param className Fully-qualified ActionScript classname, such as as |
| * <code>"spark.controls.Button"</code> |
| * @return A collection of {@link XMLName}'s representing a MXML tags, such |
| * as a <code>"Button"</code> tag in the namespace |
| * <code>"library://ns.adobe.com/flex/spark"</code>. |
| */ |
| @Override |
| public Collection<XMLName> getTagNamesForClass(String className) |
| { |
| return getMXMLManifestManager().getTagNamesForClass(className); |
| } |
| |
| /** |
| * Find all the qualified names in the manifest information that have a |
| * corresponding MXML tag whose namespace is in the specified set of |
| * namespaces. Only qualified names that originate from manifest files are |
| * included. Qualified names of components from SWCs are not included. |
| * |
| * @param namespaceURIs Set set of MXML tag namespace URIs such as: |
| * <code>"library://ns.adobe.com/flex/spark"</code> |
| * @return A collection of qualified names ( |
| * <code>spark.components.Button</code> for example ) that have correponding |
| * MXML tags in the manifest information whose namespaces are in the |
| * specified set of namespaces. |
| * @see MXMLManifestManager#getQualifiedNamesForNamespaces(Set, boolean) |
| */ |
| public Collection<String> getQualifiedClassNamesForManifestNamespaces( |
| Set<String> namespaceURIs) |
| { |
| return getMXMLManifestManager().getQualifiedNamesForNamespaces( |
| namespaceURIs, true); |
| } |
| |
| /** |
| * Test is a component is 'lookupOnly' or not. If a component is |
| * 'lookupOnly' is means this component it not expect to have source in the |
| * target namespace. |
| * |
| * @param tagName An {@code XMLName} representing an MXML tag, |
| * such as a <code>"Button"</code> tag |
| * in the namespace <code>"library://ns.adobe.com/flex/spark"</code>. |
| |
| * @return true if the component is 'lookupOnly', false otherwise. |
| */ |
| public boolean isManifestComponentLookupOnly(XMLName tagName) |
| { |
| return getMXMLManifestManager().isLookupOnly(tagName); |
| } |
| |
| @Override |
| public ICSSManager getCSSManager() |
| { |
| return cssManager; |
| } |
| |
| |
| public CSSCompilationSession getCSSCompilationSession() |
| { |
| return new CSSCompilationSession(); |
| } |
| |
| |
| /** |
| * String that replaces occurrences of "{context.root}" in the |
| * services-config.xml. The context root is specified using the |
| * context-root compiler option. |
| * |
| * @return represents the context root in the services-config.xml |
| * file. Null if the context root has not been set. |
| */ |
| public String getServciesContextRoot() |
| { |
| return servicesContextRoot; |
| } |
| |
| /** |
| * The absolute path of the services-config.xml file. This file used |
| * to configure a Flex client to talk to a BlazeDS server. |
| * |
| * @return the absolute path of the services-config.xml file. Null |
| * if the file has not been configured. |
| */ |
| @Override |
| public String getServicesXMLPath() |
| { |
| return servicesXMLPath; |
| } |
| |
| /** |
| * Configure this project to use a services-config.xml file. |
| * The services-config.xml file is used to configure a Flex client to talk |
| * to a BlazeDS server. |
| * |
| * @param path an absolute path to the services-config.xml file. |
| * @param contextRoot sets the value of the {context.root} token, which is |
| * often used in channel definitions in the services-config.xml file. |
| */ |
| @Override |
| public void setServicesXMLPath(String path, String contextRoot) |
| { |
| // Support for -services is being disabled because it is |
| // dependent on changes to flex-messaging-common.jar that |
| // were never in an official release. The code is commented |
| // out instead of removed so it can be revived in open |
| // source. |
| |
| // // Test if path or contextRoot have changed. |
| // if (((path != null) && path.equals(this.servicesXMLPath)) && |
| // ((contextRoot != null) && contextRoot.equals(this.servicesContextRoot))) |
| // { |
| // return; |
| // } |
| // |
| // this.servicesXMLPath = path; |
| // this.servicesContextRoot = contextRoot; |
| // |
| // if (path != null) |
| // { |
| // // Create a compilation unit and add it to the project. |
| // ServicesXMLCompilationUnit scu = new ServicesXMLCompilationUnit(this, path, |
| // contextRoot); |
| // |
| // ASProjectScope scope = getScope(); |
| // IDefinition def = scope.findDefinitionByName(ServicesXMLCompilationUnit.getQname(path)); |
| // ICompilationUnit unit = null; |
| // if (def != null) |
| // unit = scope.getCompilationUnitForDefinition(def); |
| // |
| // List<ICompilationUnit> toRemove = null; |
| // if (unit == null) |
| // toRemove = Collections.<ICompilationUnit>emptyList(); |
| // else |
| // toRemove = Collections.<ICompilationUnit>singletonList(unit); |
| // |
| // updateCompilationUnitsForPathChange(toRemove, |
| // Collections.<ICompilationUnit>singletonList(scu)); |
| // } |
| } |
| |
| @Override |
| public Collection<String> getLocales() { |
| return locales; |
| } |
| |
| /** |
| * Sets the locales of this project. |
| * |
| * @param locales locales to set |
| */ |
| @Override |
| public void setLocales(Collection<String> locales) |
| { |
| assert locales != null : "Locales cannot be set to null"; |
| this.locales = Collections.unmodifiableCollection(locales); |
| clean(); |
| } |
| |
| @Override |
| public String getResourceLocale(String path) |
| { |
| return this.localeDependentPaths.get(path); |
| } |
| |
| /** |
| * Sets the locale dependent path map for the project. For each entry, |
| * the key is the path of a locale dependent resource (source path or library path entry) |
| * and the value is the locale it depends on. |
| * |
| * @param localeDependentResources map that contains project's locale |
| * dependent resources |
| */ |
| @Override |
| public void setLocaleDependentResources(Map<String, String> localeDependentResources) |
| { |
| this.localeDependentPaths.clear(); |
| this.localeDependentPaths.putAll(localeDependentResources); |
| clean(); |
| } |
| |
| private Name getMNameForQName(String qname) |
| { |
| Workspace workspace = getWorkspace(); |
| IResolvedQualifiersReference reference = |
| ReferenceFactory.packageQualifiedReference(workspace, qname); |
| return reference.getMName(); |
| } |
| |
| /** |
| * Set QName for the definition of {@code <s:WebService>} tag. |
| * |
| * @param name QName of {@code WebService} class. |
| */ |
| public void setWebServiceClass(String name) |
| { |
| webServiceQName = name; |
| } |
| |
| /** |
| * @return QName of the class definition for <s:WebService> tag. |
| */ |
| public String getWebServiceQName() |
| { |
| return webServiceQName; |
| } |
| |
| /** |
| * Set QName for the definition of {@code <s:operation>} child tag of a |
| * {@code <s:WebService>} tag. |
| * |
| * @param name QName of {@code Operation} class. |
| */ |
| public void setWebServiceOperationClass(String name) |
| { |
| webServiceOperationQName = name; |
| } |
| |
| /** |
| * @return QName of the class definition for {@code <s:operation>} child tag |
| * of a {@code <s:WebService>} tag. |
| */ |
| public String getWebServiceOperationQName() |
| { |
| return webServiceOperationQName; |
| } |
| |
| /** |
| * Set {@code RemoteObjectOperation} QName. |
| * |
| * @param name QName. |
| */ |
| public void setRemoteObjectMethodClass(String name) |
| { |
| remoteObjectMethodQName = name; |
| } |
| |
| /** |
| * @return QName of the class definition for {@code <s:method>} child tag of |
| * a {@code <s:RemoteObject>} tag. |
| */ |
| public String getRemoteObjectMethodQName() |
| { |
| return remoteObjectMethodQName; |
| } |
| |
| /** |
| * Set QName for the definition of {@code <s:RemoteObject>} tag. |
| * |
| * @param name QName of {@code RemoteObject} class. |
| */ |
| public void setRemoteObjectClass(String name) |
| { |
| remoteObjectQName = name; |
| } |
| |
| /** |
| * @return QName of the class definition for {@code <s:RemoteObject>} tag. |
| */ |
| public String getRemoteObjectQName() |
| { |
| return remoteObjectQName; |
| } |
| |
| /** |
| * Set QName for the definition of {@code <s:HTTPService>} tag. |
| * |
| * @param name QName of {@code HTTPService} class. |
| */ |
| public void setHTTPServiceClass(String name) |
| { |
| httpServiceQName = name; |
| } |
| |
| /** |
| * @return QName of the class definition for {@code <s:HTTPService>} tag. |
| */ |
| public String getHTTPServiceQName() |
| { |
| return httpServiceQName; |
| } |
| |
| /** |
| * Set QName of the class definition for {@code <fx:DesignLayer>} tag. |
| * |
| * @param name QName of {@code DesignLayer} class. |
| */ |
| public void setDesignLayerClass(String name) |
| { |
| designLayerQName = name; |
| } |
| |
| /** |
| * @return QName of the class definition for {@code <fx:DesignLayer>} tag. |
| */ |
| public String getDesignLayerQName() |
| { |
| return designLayerQName; |
| } |
| |
| /** |
| * Set QName of the class definition for {@code <mx:Repeater>} tag. |
| * |
| * @param name QName of {@code Repeater} class. |
| */ |
| public void setRepeaterClass(String name) |
| { |
| repeaterQName = name; |
| } |
| |
| /** |
| * @return QName of the class definition for {@code <mx:Repeater>} tag. |
| */ |
| public String getRepeaterQName() |
| { |
| return repeaterQName; |
| } |
| |
| // |
| // New implementations of project configuration related getters and setters. |
| // |
| |
| @Override |
| public void setIncludeSources(Collection<File> sources) throws InterruptedException |
| { |
| Collection<File> files = populateIncludedSourceFiles(sources); |
| |
| super.setIncludeSources(files.toArray(new File[files.size()])); |
| } |
| |
| @Override |
| public void setActionScriptFileEncoding(String encoding) |
| { |
| actionScriptFileEncoding = encoding; |
| clean(); |
| } |
| |
| @Override |
| public String getActionScriptFileEncoding() |
| { |
| return actionScriptFileEncoding; |
| } |
| |
| @Override |
| public void setDefineDirectives(Map<String, String> defines) |
| { |
| overrideDefines(defines); |
| // TODO: This seems strange. Each call to the setter |
| // adds new defines. How do you get rid of the old ones? |
| addConfigVariables(defines); |
| clean(); |
| } |
| |
| protected void overrideDefines(Map<String, String> defines) |
| { |
| if (defines.containsKey("COMPILE::SWF")) |
| { |
| if (defines.get("COMPILE::SWF").equals("AUTO")) |
| defines.put("COMPILE::SWF", "true"); |
| } |
| if (defines.containsKey("COMPILE::JS")) |
| { |
| if (defines.get("COMPILE::JS").equals("AUTO")) |
| defines.put("COMPILE::JS", "false"); |
| } |
| } |
| |
| @Override |
| public void setExtensionLibraries(Map<File, List<String>> extensions) |
| { |
| this.extensions = extensions; |
| clean(); |
| } |
| |
| @Override |
| public Map<File, List<String>> getExtensionLibraries() |
| { |
| return extensions != null ? extensions : Collections.<File, List<String>>emptyMap(); |
| } |
| |
| /** |
| * Determines if a two sets of namespace mappings differ. |
| * @param oldMappings |
| * @param newMappings |
| * @return true if the two sets of namespace mappings differ, false otherwise. |
| */ |
| private static boolean namespaceMappingsDiffer(IMXMLNamespaceMapping[] oldMappings, List<? extends IMXMLNamespaceMapping> newMappings) |
| { |
| if (oldMappings.length != newMappings.size()) |
| return true; |
| int nMappings = oldMappings.length; |
| for (int i = 0; i < nMappings; ++i) |
| { |
| IMXMLNamespaceMapping oldMapping = oldMappings[i]; |
| IMXMLNamespaceMapping newMapping = newMappings.get(i); |
| if (!oldMapping.getManifestFileName().equals(newMapping.getManifestFileName())) |
| return true; |
| |
| if (!oldMapping.getURI().equals(newMapping.getURI())) |
| return true; |
| } |
| |
| return false; |
| |
| } |
| |
| /** |
| * Sets the mappings from MXML namespace URI to manifest files, as specified |
| * by -namespace options. |
| * |
| * @param namespaceMappings An array of {@code IMXMLNamespaceMapping} |
| * objects. |
| */ |
| @Override |
| public void setNamespaceMappings(List<? extends IMXMLNamespaceMapping> namespaceMappings) |
| { |
| if (namespaceMappingsDiffer(this.namespaceMappings, namespaceMappings)) |
| { |
| this.namespaceMappings = namespaceMappings.toArray( |
| new MXMLNamespaceMapping[namespaceMappings.size()]); |
| clean(); |
| } |
| } |
| |
| @Override |
| public List<RSLSettings> getRuntimeSharedLibraryPath() |
| { |
| return rslSettingsList != null ? rslSettingsList : Collections.<RSLSettings>emptyList(); |
| } |
| |
| @Override |
| public void setRuntimeSharedLibraryPath(List<RSLSettings> rslSettings) |
| { |
| this.rslSettingsList = rslSettings; |
| clean(); |
| } |
| |
| /** |
| * Set a list of theme files for this project. Themes are additive. The |
| * theme file closer to the end of the list has higher priorities. Calling |
| * this method will remove all the previous set theme files. |
| * |
| * @param files A list of theme file specifications. |
| */ |
| public void setThemeFiles(final List<IFileSpecification> files) |
| { |
| if (files != null) |
| this.themeFiles = ImmutableList.copyOf(files); |
| else |
| this.themeFiles = ImmutableList.of(); |
| clean(); |
| } |
| |
| /** |
| * @return A list of theme files. |
| */ |
| public List<IFileSpecification> getThemeFiles() |
| { |
| return this.themeFiles; |
| } |
| |
| @Override |
| public Set<String> computeLibraryDependencies(File targetLibrary, DependencyTypeSet dependencySet) |
| throws LibraryCircularDependencyException |
| { |
| assert targetLibrary != null : "targetLibrary may not be null"; |
| |
| LibraryDependencyGraph libraryGraph = createLibraryDependencyGraph(dependencySet); |
| return libraryGraph.getDependencies(targetLibrary.getAbsolutePath()); |
| } |
| |
| @Override |
| public List<String> computeLibraryDependencyOrder(DependencyTypeSet dependencySet) |
| throws LibraryCircularDependencyException |
| { |
| LibraryDependencyGraph libraryGraph = createLibraryDependencyGraph(dependencySet); |
| return libraryGraph.getDependencyOrder(); |
| } |
| |
| /** |
| * Create a library dependency graph based on the both the external |
| * library path and the internal library path of this project. |
| * |
| * @param dependencySet The type of dependencies that are included in the |
| * graph. Passing null or an empty set will result in all dependencies |
| * being included in the graph. |
| * @return A library dependency graph. May be null if the operation is |
| * interrupted. |
| */ |
| public LibraryDependencyGraph createLibraryDependencyGraph(DependencyTypeSet dependencySet) |
| { |
| // Get the compilation units from the swcs. |
| List<ISWC> swcs = getLibraries(); |
| Workspace w = getWorkspace(); |
| List<IRequest<IOutgoingDependenciesRequestResult, ICompilationUnit>> requests = |
| new ArrayList<IRequest<IOutgoingDependenciesRequestResult, ICompilationUnit>>(); |
| |
| // For each swc, get the compilation units. Request the semantic problems |
| // for each compilation unit to cause the dependency graph to be built. |
| Set<ICompilationUnit> swcUnits = new HashSet<ICompilationUnit>(); |
| |
| for (ISWC swc : swcs) |
| { |
| String path = swc.getSWCFile().getAbsolutePath(); |
| Collection<ICompilationUnit> units = w.getCompilationUnits(path, this); |
| swcUnits.addAll(units); |
| |
| for (ICompilationUnit unit : units) |
| requests.add(unit.getOutgoingDependenciesRequest()); |
| } |
| |
| // Iterate over the requests to cause the dependency graph to be |
| // populated. |
| for (IRequest<IOutgoingDependenciesRequestResult, ICompilationUnit> request : requests) |
| { |
| try |
| { |
| request.get(); |
| } |
| catch (InterruptedException e) |
| { |
| assert false : "Unexpected interruption"; |
| return null; |
| } |
| } |
| |
| // Now that the dependency tree of compilation units is populated, |
| // build a graph of library dependencies. |
| DependencyGraph unitGraph = getDependencyGraph(); |
| LibraryDependencyGraph libraryGraph = new LibraryDependencyGraph(); |
| |
| for (ICompilationUnit unit : swcUnits) |
| { |
| Set<Edge> dependencies = unitGraph.getOutgoingEdges(unit); |
| |
| // If a unit has no dependencies then make sure we add the swc to |
| // the graph to make sure no swcs are missing. |
| if (dependencies.size() == 0) |
| libraryGraph.addLibrary(unit.getAbsoluteFilename()); |
| |
| // For each edge look to see it the dependency is external to the swc since |
| // we only care about external dependencies. |
| // If it is an external dependency then filter based of the dependency types |
| // we care about. |
| for (Edge dependency : dependencies) |
| { |
| // Test if the edge is between different swcs |
| ICompilationUnit from = dependency.getFrom(); |
| ICompilationUnit to = dependency.getTo(); |
| |
| /* Check if the compilation units live in different |
| * swcs. If so, add a dependency between the swcs. |
| */ |
| if (isInterSWCDependency(from, to)) |
| { |
| if (dependencySet == null || |
| dependency.typeInSet(dependencySet) || |
| dependencySet.isEmpty()) |
| { |
| libraryGraph.addLibrary(from.getAbsoluteFilename()); |
| libraryGraph.addLibrary(to.getAbsoluteFilename()); |
| libraryGraph.addDependency(from.getAbsoluteFilename(), to.getAbsoluteFilename(), |
| dependency.getNamedDependencies()); |
| } |
| } |
| } |
| } |
| |
| return libraryGraph; |
| } |
| |
| /** |
| * Test if the two compilation units live in different SWCs. |
| * |
| * @param from |
| * @param to |
| * @return |
| */ |
| private boolean isInterSWCDependency(ICompilationUnit from, ICompilationUnit to) |
| { |
| if (from.getAbsoluteFilename() != null && |
| !from.getAbsoluteFilename().equals(to.getAbsoluteFilename())) |
| { |
| // If the compilation units are from different SWCs, check the |
| // shadowed definitions to make sure the dependency doesn't also |
| // live in the same SWC. If the same definition, with the same |
| // timestamp is found in the same SWC as a shadowed definition |
| // then don't consider this an inter-SWC dependency. |
| |
| // Get if the "to" compilation unit has any equivalent shadowed |
| // definitions that are in the same SWC as the "from" unit. |
| if (hasShadowedCompulationUnit(to, from.getAbsoluteFilename())) |
| return false; |
| |
| // Test if the "from" unit has an equivalent in the "to" unit's SWC. |
| if (hasShadowedCompulationUnit(from, to.getAbsoluteFilename())) |
| return false; |
| |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Test if the given unit has any shadowed definitions that live |
| * in the given swc path. |
| * |
| * @param unit |
| * @param swcPath |
| * @return true if a shadowed definition is found, false otherwise. |
| */ |
| private boolean hasShadowedCompulationUnit(ICompilationUnit unit, String swcPath) |
| { |
| List<IDefinition> definitionPromises = unit.getDefinitionPromises(); |
| if (definitionPromises == null || definitionPromises.size() == 0) |
| return false; |
| |
| ASProjectScope scope = getScope(); |
| Set<IDefinition> toDefs = scope.getShadowedDefinitions(definitionPromises.get(0)); |
| if (toDefs != null) |
| { |
| for (IDefinition def : toDefs) |
| { |
| ICompilationUnit shadowedUnit = scope.getCompilationUnitForDefinition(def); |
| |
| // Test if a shadowed unit is in the same swc. |
| if (swcPath.equals(shadowedUnit.getAbsoluteFilename())) |
| { |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Files from the parameter list are added as is and directories are recursively |
| * expanded into files. |
| * |
| * @param includedSources Collection of files. Can be a mix of files and directories. |
| * @return Set of {@link File} where each {@link File} will return true when isFile() |
| * is called. |
| */ |
| private Set<File> populateIncludedSourceFiles(Collection<File> includedSources) |
| { |
| final Set<File> includedSourceFiles = new HashSet<File>(); |
| for (final File file : includedSources) |
| { |
| if (file.isFile()) |
| { |
| includedSourceFiles.add(file); |
| continue; |
| } |
| else if (file.isDirectory()) |
| { |
| for (final File fileInFolder : |
| FileUtils.listFiles(file, new String[] {"as", "mxml"}, true)) |
| { |
| includedSourceFiles.add(fileInFolder); |
| } |
| } |
| } |
| return includedSourceFiles; |
| } |
| |
| @Override |
| public List<String> getThemeNames() |
| { |
| return transform(this.getThemeFiles(), ThemeUtilities.THEME_FILE_TO_NAME); |
| } |
| |
| @Override |
| public void clean() |
| { |
| super.clean(); |
| manifestManager = null; |
| } |
| |
| @Override |
| public boolean isFlex() |
| { |
| return this.isFlex; |
| } |
| |
| @Override |
| public void setFlex(boolean value) |
| { |
| this.isFlex = value; |
| } |
| |
| @Override |
| public void setExcludeNativeJSLibraries(final boolean value) { |
| |
| } |
| |
| @Override |
| public String getActualPackageName(String packageName) |
| { |
| if (packageName.startsWith("window.")) |
| return packageName.substring(7); |
| if (packageName.equals("window")) |
| return ""; |
| return packageName; |
| } |
| |
| @Override |
| public IDefinition doubleCheckAmbiguousDefinition(ASScope scope, String name, IDefinition def1, IDefinition def2) |
| { |
| IScopedDefinition scopeDef = scope.getContainingDefinition(); |
| String thisPackage = null; |
| if (scopeDef != null) |
| thisPackage = scopeDef.getPackageName(); |
| else |
| { |
| while (!(scope instanceof PackageScope)) |
| { |
| scope = scope.getContainingScope(); |
| } |
| if (!(scope instanceof PackageScope)) |
| return null; |
| thisPackage = ((PackageScope)scope).getDefinition().getBaseName(); |
| } |
| String package1 = def1.getPackageName(); |
| String package2 = def2.getPackageName(); |
| // if the conflicts is against a class in the global/window package |
| // then return the other one. |
| if (package1.equals(thisPackage) && package2.length() == 0) |
| return def1; |
| if (package2.equals(thisPackage) && package1.length() == 0) |
| return def2; |
| if (package1.length() == 0 || package2.length() == 0) |
| { |
| // now check to see if the class was imported in the window package. |
| ASScope pkgScope = scope; |
| while (!(pkgScope instanceof PackageScope)) |
| pkgScope = pkgScope.getContainingScope(); |
| String[] imports = pkgScope.getImports(); |
| String windowName = "window." + name; |
| boolean usingWindow = false; |
| for (String imp : imports) |
| { |
| if (imp.equals(windowName)) |
| { |
| usingWindow = true; |
| break; |
| } |
| } |
| // if they did not import via the window package, then assume |
| // that they meant the one they did import |
| if (!usingWindow) |
| { |
| return package1.length() == 0 ? def2 : def1; |
| } |
| // otherwise fall through to ambiguous because they need to qualify |
| // with the package name, even if it is 'window' |
| } |
| return null; |
| } |
| |
| public boolean useStrictXML() |
| { |
| return this.strictXML; |
| } |
| |
| public boolean setStrictXML(boolean strictXML) |
| { |
| return this.strictXML = strictXML; |
| } |
| |
| /** |
| * The base for compiler-generated id's on instance tags that need an id but |
| * don't have one specified in MXML. Compiler-generated ids for instance |
| * tags have the form #0, #1, etc. The old compiler generated an id of the |
| * form "_MyComponent_Button3", but we prefer short names that are the same |
| * in all classes, because these create smaller SWFs. Also, the compiler can |
| * be simpler and faster if it doesn't have to track how many instances of |
| * each type it has seen in a class. Rather than using some weird Unicode |
| * character, we've chosen # as a normal ASCII character that will look OK |
| * in the debugger but not conflict with any developer-specified id, since |
| * it isn't allowed in an ActionScript identifier or MXML id. It also can't |
| * conflict with any dynamic properties, because MXML classes are sealed. |
| */ |
| public String getGeneratedIDBase() |
| { |
| return "#"; |
| } |
| |
| @Override |
| public boolean isCompatibleOverrideReturnType(IFunctionDefinition func, ITypeDefinition overrideDefinition, ITypeDefinition baseDefinition) |
| { |
| if (baseDefinition == overrideDefinition) |
| return true; |
| if (targetSettings != null && targetSettings.getAllowSubclassOverrides() && overrideDefinition != null && baseDefinition != null) |
| { |
| if (overrideDefinition.isInstanceOf(baseDefinition.getQualifiedName(), this)) |
| return true; |
| FunctionDefinition f = (FunctionDefinition)func; |
| IMetaTag[] metas = f.getAllMetaTags(); |
| for (IMetaTag meta : metas) |
| { |
| if (meta.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_SWFOVERRIDE)) |
| { |
| IMetaTagAttribute attr = meta.getAttribute(IMetaAttributeConstants.NAME_SWFOVERRIDE_RETURNS); |
| if (attr != null) |
| { |
| if (attr.getValue().equals(baseDefinition.getQualifiedName())) |
| return true; |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean isCompatibleOverrideParameterType( |
| IFunctionDefinition func, ITypeDefinition overrideDefinition, |
| ITypeDefinition baseDefinition, int i) |
| { |
| if (baseDefinition == overrideDefinition) |
| return true; |
| if (targetSettings != null && targetSettings.getAllowSubclassOverrides() && overrideDefinition != null && baseDefinition != null) |
| { |
| if (overrideDefinition.isInstanceOf(baseDefinition.getQualifiedName(), this)) |
| return true; |
| FunctionDefinition f = (FunctionDefinition)func; |
| IMetaTag[] metas = f.getAllMetaTags(); |
| for (IMetaTag meta : metas) |
| { |
| if (meta.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_SWFOVERRIDE)) |
| { |
| IMetaTagAttribute attr = meta.getAttribute(IMetaAttributeConstants.NAME_SWFOVERRIDE_PARAMS); |
| if (attr != null) |
| { |
| String paramList = attr.getValue(); |
| String[] parts; |
| if (paramList.contains(",")) |
| parts = paramList.split(","); |
| else |
| { |
| parts = new String[1]; |
| parts[0] = paramList; |
| } |
| if (parts[i].equals(baseDefinition.getQualifiedName())) |
| return true; |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean isValidTypeConversion(IASNode node, IDefinition actualDefinition, IDefinition expectedDefinition, FunctionDefinition func) |
| { |
| if (actualDefinition.getBaseName().equals(IASLanguageConstants._int) && |
| expectedDefinition.getBaseName().equals(IASLanguageConstants.Function)) |
| { |
| // see if this is a call to Array.sort with sort flags |
| if (node.getParent().getNodeID() == ASTNodeID.ContainerID && |
| node.getParent().getParent().getNodeID() == ASTNodeID.FunctionCallID) |
| { |
| if (func.getParent().getQualifiedName().equals(IASLanguageConstants.Array) && |
| func.getBaseName().equals("sort")) |
| { |
| return true; |
| } |
| } |
| } |
| if (func == null) return false; |
| IMetaTag[] metas = func.getAllMetaTags(); |
| for (IMetaTag meta : metas) |
| { |
| if (meta.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_SWFOVERRIDE)) |
| { |
| IMetaTagAttribute attr = meta.getAttribute(IMetaAttributeConstants.NAME_SWFOVERRIDE_ALTPARAMS); |
| if (attr != null) |
| { |
| // format is expectedQName:allowedQName,expectedQName:allowedQName. |
| // we don't know which parameter it is so we're assuming for now that any mapping |
| // applies to all occurences of that type in the parameter list |
| String paramList = attr.getValue(); |
| String[] paramMap; |
| if (paramList.contains(",")) |
| paramMap = paramList.split(","); |
| else |
| { |
| paramMap = new String[1]; |
| paramMap[0] = paramList; |
| } |
| for (String item : paramMap) |
| { |
| String[] parts = item.split(":"); |
| if (expectedDefinition.getQualifiedName().equals(parts[0])) |
| if (((ITypeDefinition)actualDefinition).isInstanceOf(parts[1], this)) |
| return true; |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * List of external libraries so it can be overridden |
| */ |
| public List<String> getCompilerExternalLibraryPath(Configuration config) |
| { |
| List<String> list = config.getCompilerSwfExternalLibraryPath(); |
| if (list != null && list.size() > 0) |
| return list; |
| return config.getCompilerExternalLibraryPath(); |
| } |
| |
| /** |
| * List of libraries so it can be overridden |
| */ |
| public List<String> getCompilerLibraryPath(Configuration config) |
| { |
| List<String> list = config.getCompilerSwfLibraryPath(); |
| if (list != null && list.size() > 0) |
| return list; |
| return config.getCompilerLibraryPath(); |
| } |
| |
| /** |
| * List of libraries so it can be overridden |
| */ |
| public List<MXMLNamespaceMapping> getCompilerNamespacesManifestMappings(Configuration config) |
| { |
| return config.getCompilerNamespacesManifestMappings(); |
| } |
| |
| @Override |
| public boolean isPlatformRule(ICSSRule rule) { |
| return true; |
| } |
| |
| } |