| /* |
| * |
| * 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.util; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Iterator; |
| import java.util.Set; |
| import java.util.HashSet; |
| |
| /** |
| * Stores the mappings of name and uri to classname. |
| * |
| */ |
| public class NameMappings |
| { |
| public NameMappings() |
| { |
| namespaceMap = new HashMap<String, Map<String,String>>(); |
| lookupOnly = new HashMap<String, Set<String>>(); |
| } |
| |
| private Map<String, Map<String,String>> namespaceMap; |
| private Map<String, Set<String>> lookupOnly; |
| |
| public NameMappings copy() |
| { |
| NameMappings m = new NameMappings(); |
| for (Iterator<String> i = namespaceMap.keySet().iterator(); i.hasNext(); ) |
| { |
| String uri = i.next(); |
| Map<String, String> classMap = namespaceMap.get(uri); |
| m.namespaceMap.put(uri, new HashMap<String,String>(classMap)); |
| } |
| m.lookupOnly.putAll(lookupOnly); |
| return m; |
| } |
| |
| public String lookupPackageName(String nsURI, String localPart) |
| { |
| String className = lookupClassName(nsURI, localPart); |
| if (className == null) |
| { |
| return null; |
| } |
| int index = className.indexOf(":"); |
| return (index == -1) ? "" : className.substring(0, index); |
| } |
| |
| public String lookupClassName(String nsURI, String localPart) |
| { |
| Map<String, String> classMap = namespaceMap.get(nsURI); |
| return classMap == null ? null : classMap.get(localPart); |
| } |
| |
| /** |
| * Look up namespace;classname against registered entries, then fault to package-style namespace handling |
| * NOTE: the contract here is that a null return value definitely indicates a missing definition, but a non-null |
| * return value *by no means* ensures that a definition will be available. E.g. an entry in a manifest doesn't mean |
| * that the backing code is correct, defines the specified class or even exists. Also, for package-style namespaces |
| * we simply concatenate the parameters together, since (e.g.) checking the presence or absence of a suitable entry |
| * on the classpath gives a similarly non-definitive answer. |
| */ |
| public String resolveClassName(String namespaceURI, String localPart) |
| { |
| String className = lookupClassName(namespaceURI, localPart); |
| |
| if (className == null) |
| { |
| // C: if namespaceURI is in the form of p1.p2...pn.*... |
| // HIGHLY recommend handling this as old compiler did. --rg |
| if ("*".equals(namespaceURI)) |
| { |
| className = localPart; |
| } |
| else if (namespaceURI.length() > 2 && namespaceURI.endsWith(".*")) |
| { |
| className = namespaceURI.substring(0, namespaceURI.length() - 2) + ':' + localPart; |
| className = className.intern(); |
| } |
| } |
| |
| return className; |
| } |
| |
| public Map<String, String> getNamespace(String nsURI) |
| { |
| return namespaceMap.get(nsURI); |
| } |
| |
| public Set<String> getNamespaces() |
| { |
| return namespaceMap.keySet(); |
| } |
| |
| public void addMappings( NameMappings other ) |
| { |
| for (Iterator<Map.Entry<String, Map<String,String>>> nit = other.namespaceMap.entrySet().iterator(); nit.hasNext();) |
| { |
| Map.Entry<String, Map<String,String>> e = nit.next(); |
| String namespaceURI = e.getKey(); |
| Map<String, String> mappings = e.getValue(); |
| |
| for (Iterator<Map.Entry<String, String>> it = mappings.entrySet().iterator(); it.hasNext();) |
| { |
| Map.Entry<String, String> lc = it.next(); |
| String local = lc.getKey(); |
| String className = lc.getValue(); |
| |
| addClass( namespaceURI, local, className ); |
| } |
| } |
| } |
| |
| public boolean addClass(String namespaceURI, String localPart, String className) |
| { |
| Map<String, String> classMap = null; |
| |
| if (namespaceMap.containsKey(namespaceURI)) |
| { |
| classMap = namespaceMap.get(namespaceURI); |
| } |
| else |
| { |
| classMap = new HashMap<String, String>(); |
| namespaceMap.put(namespaceURI.intern(), classMap); |
| } |
| |
| String current = classMap.get(localPart); |
| if (current == null) |
| { |
| classMap.put(localPart.intern(), className.intern()); |
| } |
| else if (! current.equals(className)) |
| { |
| return false; |
| } |
| return true; |
| } |
| |
| public void addLookupOnly(String namespaceURI, String cls) |
| { |
| Set classes = lookupOnly.get(namespaceURI); |
| |
| if (classes == null) |
| { |
| classes = new HashSet<String>(); |
| lookupOnly.put(namespaceURI, classes); |
| } |
| |
| classes.add(cls); |
| } |
| |
| public boolean isLookupOnly(String namespaceURI, String cls) |
| { |
| boolean result = false; |
| Set classes = lookupOnly.get(namespaceURI); |
| |
| if (classes != null) |
| { |
| result = classes.contains(cls); |
| } |
| |
| return result; |
| } |
| } |