All Downloads are FREE. Search and download functionalities are using the official Maven repository.

juzu.impl.plugin.asset.AssetsMetaModel Maven / Gradle / Ivy

There is a newer version: 1.2.0
Show newest version
/*
 * Copyright 2013 eXo Platform SAS
 *
 * Licensed 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 juzu.impl.plugin.asset;

import juzu.impl.asset.AssetServer;
import juzu.impl.common.MethodInvocation;
import juzu.impl.common.MethodInvocationResolver;
import juzu.impl.common.Name;
import juzu.impl.compiler.ElementHandle;
import juzu.impl.compiler.MessageCode;
import juzu.impl.compiler.ProcessingContext;
import juzu.impl.compiler.ProcessingException;
import juzu.impl.metamodel.Key;
import juzu.impl.metamodel.MetaModelObject;
import juzu.impl.plugin.application.metamodel.ApplicationMetaModel;

import javax.tools.FileObject;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;

/** @author Julien Viet */
public class AssetsMetaModel extends MetaModelObject implements MethodInvocationResolver {

  /** . */
  public static final MessageCode UNRESOLVED_ASSET = new MessageCode("UNRESOLVED_ASSET", "The application asset %1s cannot be resolved");

  /** . */
  public final static Key KEY = Key.of(AssetsMetaModel.class);

  /** . */
  private final HashMap assets = new HashMap();

  /**
   * Links resource URLs to target: some resources may have the same target, it should
   * be an issue that we detect in the resolving phase and produce an error.
   */
  private final HashMap resources = new HashMap();

  /** . */
  private final ElementHandle.Package pkg;

  public AssetsMetaModel(ElementHandle.Package pkg) {
    this.pkg = pkg;
  }

  public void addAsset(Asset asset) {
    assets.put(asset.key, asset);
  }

  public void removeAsset(Asset asset) {
    assets.remove(asset.key);
  }

  /**
   * Associate a resource with a physical path in the application.
   *
   * @param path the resource path
   * @param resource the resource
   */
  public void addResource(String path, URL resource) {
    URL existing = resources.get(path);
    if (existing != null) {
      throw new UnsupportedOperationException("Cannot add resource " + path + " : added " + resource + " != existing " + existing);
    } else {
      resources.put(path, resource);
    }
  }

  /**
   * Remove a resource association from the application.
   *
   * @param path the resource path
   * @param resource the resource
   */
  public void removeResource(String path, URL resource) {
    URL existing = resources.get(path);
    if (resource.equals(existing)) {
      resources.remove(path);
    } else {
      throw new UnsupportedOperationException("Resource conflict for resource " + path + " : removed " + resource +
          " not matched by existing " + existing);
    }
  }

  /**
   * Resolve a relative resource for this application, this method does not modify the current application.
   *
   * @param path the resource value
   * @return the related resource URL or null if it cannot be resolved
   * @throws ProcessingException relate any processing issue
   */
  public URL resolveResource(String path) throws ProcessingException {
    ApplicationMetaModel application = (ApplicationMetaModel)metaModel;
    ProcessingContext context = application.getProcessingContext();
    boolean relative = path.length() == 0 || path.charAt(0) != '/';
    if (relative) {
      context.info("Resolving classpath asset " + path);
      Name qn = application.getHandle().getPackageName().append("assets");
      FileObject src;
      try {
        src = context.resolveResourceFromSourcePath(pkg, qn, path);
      }
      catch (Exception e) {
        throw UNRESOLVED_ASSET.failure(path).initCause(e);
      }
      if (src != null) {
        URI uri = src.toUri();
        context.info("Found asset " + path + " on source path " + uri);
        try {
          String scheme = uri.getScheme();
          if (scheme == null) {
            uri = new URI("file:" + uri);
          }
          return uri.toURL();
        }
        catch (URISyntaxException e) {
          throw UNRESOLVED_ASSET.failure(uri).initCause(e);
        }
        catch (MalformedURLException e) {
          throw UNRESOLVED_ASSET.failure(uri).initCause(e);
        }
      } else {
        context.info("Could not find asset " + path + " on source path");
        return null;
      }
    } else {
      return null;
    }
  }

  public Map getResources() {
    return resources;
  }

  public Iterable getAssets() {
    return assets.values();
  }

  public Iterable getAssets(final String type) {
    return new Iterable() {
      public Iterator iterator() {
        final Iterator i = assets.values().iterator();
        return new Iterator() {
          Asset next = null;
          public boolean hasNext() {
            while (next == null && i.hasNext()) {
              Asset asset = i.next();
              if (asset.type.equals(type)) {
                next = asset;
              }
            }
            return next != null;
          }
          public Asset next() {
            if (hasNext()) {
              Asset tmp = next;
              next = null;
              return tmp;
            } else {
              throw new NoSuchElementException();
            }
          }
          public void remove() {
            throw new UnsupportedOperationException();
          }
        };
      }
    };
  }

  public void removeAssets(String type) {
    for (Iterator i = assets.values().iterator();i.hasNext();) {
      Asset asset = i.next();
      if (asset.type.equals(type)) {
        i.remove();
      }
    }
  }

  public MethodInvocation resolveMethodInvocation(String typeName, String methodName, Map parameterMap) {
    if ("Assets".equals(typeName) && methodName.equals("url")) {
      String path = parameterMap.get("path");
      if (path != null) {
        return new MethodInvocation(AssetServer.class.getName(), "renderAssetURLByPath", Collections.singletonList(path));
      } else {
        String id = parameterMap.get("id");
        if (id != null) {
          return new MethodInvocation(AssetServer.class.getName(), "renderAssetURLById", Collections.singletonList(id));
        }
      }
    }
    return null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy