org.symbian.tools.mtw.core/src/org/symbian/tools/tmw/core/internal/runtimes/RuntimeClasspathManager.java
changeset 461 7a8f9fa8d278
child 463 aea4c83725d8
equal deleted inserted replaced
460:c0bff5ed874c 461:7a8f9fa8d278
       
     1 /**
       
     2  * Copyright (c) 2010 Symbian Foundation and/or its subsidiary(-ies).
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of the License "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Symbian Foundation - initial contribution.
       
    11  * Contributors:
       
    12  * Description:
       
    13  * Overview:
       
    14  * Details:
       
    15  * Platforms/Drives/Compatibility:
       
    16  * Assumptions/Requirement/Pre-requisites:
       
    17  * Failures and causes:
       
    18  */
       
    19 package org.symbian.tools.tmw.core.internal.runtimes;
       
    20 
       
    21 import java.util.Arrays;
       
    22 import java.util.Collection;
       
    23 import java.util.Collections;
       
    24 import java.util.HashMap;
       
    25 import java.util.HashSet;
       
    26 import java.util.LinkedList;
       
    27 import java.util.Map;
       
    28 import java.util.Set;
       
    29 
       
    30 import org.eclipse.core.runtime.CoreException;
       
    31 import org.eclipse.core.runtime.IConfigurationElement;
       
    32 import org.eclipse.core.runtime.Platform;
       
    33 import org.eclipse.wst.common.project.facet.core.IFacetedProject;
       
    34 import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
       
    35 import org.eclipse.wst.common.project.facet.core.IVersion;
       
    36 import org.eclipse.wst.common.project.facet.core.IVersionExpr;
       
    37 import org.eclipse.wst.common.project.facet.core.util.internal.VersionExpr;
       
    38 import org.eclipse.wst.common.project.facet.core.util.internal.Versionable;
       
    39 import org.eclipse.wst.jsdt.core.IIncludePathEntry;
       
    40 import org.symbian.tools.tmw.core.TMWCore;
       
    41 import org.symbian.tools.tmw.core.internal.projects.LazyIncludePathProvider;
       
    42 import org.symbian.tools.tmw.core.internal.projects.StaticIncludePathProvider;
       
    43 import org.symbian.tools.tmw.core.projects.IFacetIncludePathProvider;
       
    44 import org.symbian.tools.tmw.core.projects.IMTWProject;
       
    45 import org.symbian.tools.tmw.core.runtimes.IMobileWebRuntime;
       
    46 
       
    47 @SuppressWarnings("restriction")
       
    48 public class RuntimeClasspathManager {
       
    49     private static final class VersionedEntry<T> {
       
    50         protected final IVersionExpr versionExpression;
       
    51         protected final T entry;
       
    52 
       
    53         public VersionedEntry(String versionExpression, T entry) {
       
    54             if (versionExpression == null) {
       
    55                 this.versionExpression = null;
       
    56             } else {
       
    57                 IVersionExpr expr;
       
    58                 try {
       
    59                     expr = new VersionExpr<Version>(new VersionableObject(), versionExpression, null);
       
    60                 } catch (CoreException e) {
       
    61                     expr = null;
       
    62                     TMWCore.log(null, e);
       
    63                 }
       
    64                 this.versionExpression = expr;
       
    65             }
       
    66             this.entry = entry;
       
    67         }
       
    68 
       
    69         public boolean matches(String version) {
       
    70             if (versionExpression == null) { // Any version
       
    71                 return true;
       
    72             }
       
    73             if (version == null) { // Unspecified
       
    74                 return false;
       
    75             }
       
    76             return versionExpression.check(new Version(version));
       
    77         }
       
    78     }
       
    79 
       
    80     private static final class VersionableObject extends Versionable<Version> {
       
    81         @Override
       
    82         public String getPluginId() {
       
    83             return TMWCore.PLUGIN_ID;
       
    84         }
       
    85 
       
    86         @Override
       
    87         public String createVersionNotFoundErrMsg(String verstr) {
       
    88             return "Version not found";
       
    89         }
       
    90     }
       
    91 
       
    92     private static final class Version implements IVersion {
       
    93         private final String version;
       
    94 
       
    95         public Version(String version) {
       
    96             this.version = version;
       
    97         }
       
    98 
       
    99         public int compareTo(Object o) {
       
   100             return version.compareTo(((IVersion) o).getVersionString());
       
   101         }
       
   102 
       
   103         public String getVersionString() {
       
   104             return version;
       
   105         }
       
   106     }
       
   107 
       
   108     private final Map<String, Collection<VersionedEntry<Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>>>> providers = new HashMap<String, Collection<VersionedEntry<Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>>>>();
       
   109     private final boolean ready = false;
       
   110 
       
   111     public IIncludePathEntry[] getProjectClasspathEntries(IFacetedProject project) {
       
   112         collectProviders();
       
   113         final IMTWProject p = TMWCore.getDefault().create(project.getProject());
       
   114         if (p != null) {
       
   115             final IMobileWebRuntime runtime = p.getTargetRuntime();
       
   116             final Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>> facetToEntry;
       
   117             if (runtime != null) {
       
   118                 facetToEntry = join(getMatchingEntries(runtime.getId(), runtime.getVersion(), providers));
       
   119             } else {
       
   120                 facetToEntry = join(getMatchingEntries(null, null, providers));
       
   121             }
       
   122             final Collection<IFacetIncludePathProvider[]> entries = getMatchingEntries(null, null, facetToEntry);
       
   123             final Set<IProjectFacetVersion> facets = project.getProjectFacets();
       
   124             for (IProjectFacetVersion facet : facets) {
       
   125                 entries.addAll(getMatchingEntries(facet.getProjectFacet().getId(), facet.getVersionString(),
       
   126                         facetToEntry));
       
   127             }
       
   128             final Collection<IIncludePathEntry> pathEntries = new HashSet<IIncludePathEntry>();
       
   129             for (IFacetIncludePathProvider[] providers : entries) {
       
   130                 for (IFacetIncludePathProvider provider : providers) {
       
   131                     pathEntries.addAll(Arrays.asList(provider.getEntries(p)));
       
   132                 }
       
   133             }
       
   134             return pathEntries.toArray(new IIncludePathEntry[pathEntries.size()]);
       
   135         }
       
   136         return new IIncludePathEntry[0];
       
   137     }
       
   138 
       
   139     @SuppressWarnings({ "rawtypes", "unchecked" })
       
   140     private synchronized void collectProviders() {
       
   141         if (!ready) {
       
   142             final IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(
       
   143                     TMWCore.PLUGIN_ID, "runtimeIncludePath");
       
   144             final Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>> entries = collectFaceletEntries(elements);
       
   145             final VersionedEntry<Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>> entry = new VersionedEntry(
       
   146                     null, entries);
       
   147             providers.put(null, Collections.singleton(entry));
       
   148             for (IConfigurationElement element : elements) {
       
   149                 if ("runtime-include-path".equals(element.getName())) {
       
   150                     final String id = element.getAttribute("id");
       
   151                     Collection<VersionedEntry<Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>>> versions = providers
       
   152                             .get(id);
       
   153                     if (versions == null) {
       
   154                         versions = new LinkedList<RuntimeClasspathManager.VersionedEntry<Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>>>();
       
   155                         providers.put(id, versions);
       
   156                     }
       
   157                     final Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>> facetProviders = new HashMap<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>();
       
   158                     final IFacetIncludePathProvider[] collection = collectProviders(element.getChildren());
       
   159                     final VersionedEntry<IFacetIncludePathProvider[]> ent = new VersionedEntry(null, collection);
       
   160                     facetProviders.put(null, Collections.singleton(ent));
       
   161                     facetProviders.putAll(collectFaceletEntries(element.getChildren()));
       
   162                     final VersionedEntry<Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>> ver = new VersionedEntry<Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>>(
       
   163                             element.getAttribute("version"), facetProviders);
       
   164                     versions.add(ver);
       
   165                 }
       
   166             }
       
   167         }
       
   168     }
       
   169 
       
   170     private IFacetIncludePathProvider[] collectProviders(IConfigurationElement[] children) {
       
   171         final Collection<IFacetIncludePathProvider> providers = new LinkedList<IFacetIncludePathProvider>();
       
   172         for (IConfigurationElement element : children) {
       
   173             if ("include-path-entry".equals(element.getName())) {
       
   174                 providers.add(new StaticIncludePathProvider(element));
       
   175             } else if ("include-path-provider".equals(element.getName())) {
       
   176                 providers.add(new LazyIncludePathProvider(element));
       
   177             }
       
   178         }
       
   179         return providers.toArray(new IFacetIncludePathProvider[providers.size()]);
       
   180     }
       
   181 
       
   182     public Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>> collectFaceletEntries(
       
   183             IConfigurationElement[] elements) {
       
   184         final Map<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>> faceletsToProviders = new HashMap<String, Collection<VersionedEntry<IFacetIncludePathProvider[]>>>();
       
   185         for (IConfigurationElement element : elements) {
       
   186             if ("facet-include-path".equals(element.getName())) {
       
   187                 final IFacetIncludePathProvider[] providers = collectProviders(element.getChildren());
       
   188                 final VersionedEntry<IFacetIncludePathProvider[]> versionedEntry = new VersionedEntry<IFacetIncludePathProvider[]>(
       
   189                         element.getAttribute("version"), providers);
       
   190                 final String id = element.getAttribute("facelet-id");
       
   191                 Collection<VersionedEntry<IFacetIncludePathProvider[]>> provs = faceletsToProviders.get(id);
       
   192                 if (provs == null) {
       
   193                     provs = new LinkedList<RuntimeClasspathManager.VersionedEntry<IFacetIncludePathProvider[]>>();
       
   194                     faceletsToProviders.put(id, provs);
       
   195                 }
       
   196                 provs.add(versionedEntry);
       
   197             }
       
   198         }
       
   199         return faceletsToProviders;
       
   200     }
       
   201 
       
   202     private <T, V> Map<T, Collection<V>> join(Collection<Map<T, Collection<V>>> maps) {
       
   203         final Map<T, Collection<V>> res = new HashMap<T, Collection<V>>();
       
   204         for (Map<T, Collection<V>> map : maps) {
       
   205             for (Map.Entry<T, Collection<V>> entry : map.entrySet()) {
       
   206                 if (res.containsKey(entry.getKey())) {
       
   207                     res.get(entry.getKey()).addAll(entry.getValue());
       
   208                 } else {
       
   209                     res.put(entry.getKey(), new LinkedList<V>(entry.getValue()));
       
   210                 }
       
   211             }
       
   212         }
       
   213         return res;
       
   214     }
       
   215 
       
   216     private <T> Collection<T> getMatchingEntries(String id, String version,
       
   217             Map<String, Collection<VersionedEntry<T>>> map) {
       
   218         final Collection<VersionedEntry<T>> entries = new LinkedList<VersionedEntry<T>>();
       
   219         Collection<VersionedEntry<T>> versionedEntries = map.get(null);
       
   220         if (versionedEntries != null) {
       
   221             entries.addAll(versionedEntries);
       
   222         }
       
   223         if (id != null) {
       
   224             versionedEntries = map.get(id);
       
   225             if (versionedEntries != null) {
       
   226                 entries.addAll(versionedEntries);
       
   227             }
       
   228         }
       
   229         final Collection<T> res = new LinkedList<T>();
       
   230         for (VersionedEntry<T> versionedEntry : entries) {
       
   231             if (versionedEntry.matches(version)) {
       
   232                 res.add(versionedEntry.entry);
       
   233             }
       
   234         }
       
   235         return res;
       
   236     }
       
   237 }