Package org.wicketstuff.mergedresources.annotations

Source Code of org.wicketstuff.mergedresources.annotations.ContributionScanner$WeightedResourceSpec

/**
* Copyright 2010 Molindo GmbH
*
* 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 org.wicketstuff.mergedresources.annotations;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.util.string.Strings;
import org.wicketstuff.config.MatchingResources;
import org.wicketstuff.mergedresources.ResourceSpec;

import edu.umd.cs.findbugs.annotations.SuppressWarnings;

/**
* Gather page resources to merge, depends on {@link CssContribution} and
* {@link JsContribution} annotations.
*
* Helper to make using wicketstuff-merged-resources easier.
*/
public class ContributionScanner {

  private static final String DEFAULT_PATH_JS = "all.js";
  private static final String DEFAULT_PATH_CSS = "all.css";

  private final Map<String, SortedSet<WeightedResourceSpec>> _contributions;

  public ContributionScanner(String packageName) {
    MatchingResources resources = new MatchingResources(getPatternForPackage(packageName));

    _contributions = scan(resources);
  }

  private Map<String, SortedSet<WeightedResourceSpec>> scan(MatchingResources resources) {
    Map<String, SortedSet<WeightedResourceSpec>> contributions = new HashMap<String, SortedSet<WeightedResourceSpec>>();

    for (Class<?> cls : resources.getAnnotatedMatches(JsContribution.class)) {
      JsContribution a = cls.getAnnotation(JsContribution.class);
      addJsContributions(cls, a, contributions);
    }

    for (Class<?> cls : resources.getAnnotatedMatches(CssContribution.class)) {
      CssContribution a = cls.getAnnotation(CssContribution.class);
      addCssContributions(cls, a, contributions);
    }

    for (Class<?> cls : resources.getAnnotatedMatches(CssContributions.class)) {
      CssContributions cssMulti = cls.getAnnotation(CssContributions.class);
      for (CssContribution css : cssMulti.value()) {
        addCssContributions(cls, css, contributions);
      }
    }

    for (Class<?> cls : resources.getAnnotatedMatches(ResourceContribution.class)) {
      ResourceContribution resource = cls.getAnnotation(ResourceContribution.class);
      addResourceContributions(cls, resource, contributions);
    }

    for (Map.Entry<String, SortedSet<WeightedResourceSpec>> e : contributions.entrySet()) {
      e.setValue(Collections.unmodifiableSortedSet(e.getValue()));
    }

    return Collections.unmodifiableMap(contributions);
  }

  private void addJsContributions(Class<?> scope, JsContribution js,
      Map<String, SortedSet<WeightedResourceSpec>> contributions) {
    for (String file : js.value()) {
      if (Strings.isEmpty(file)) {
        file = scope.getSimpleName() + ".js";
      }

      String path = Strings.isEmpty(js.path()) ? DEFAULT_PATH_JS : js.path();
      SortedSet<WeightedResourceSpec> specs = contributions.get(path);
      if (specs == null) {
        specs = new TreeSet<WeightedResourceSpec>(WeightedResourceSpecComparator.INSTANCE);
        contributions.put(path, specs);
      }
      if (!specs.add(new WeightedResourceSpec(scope, file, js.order()))) {
        throw new WicketRuntimeException("duplicate resource contribution: " + js + ", scope=" + scope);
      }
    }
  }

  private void addCssContributions(Class<?> scope, CssContribution css,
      Map<String, SortedSet<WeightedResourceSpec>> contributions) {
    for (String file : css.value()) {
      if (Strings.isEmpty(file)) {
        file = getDefaultCssFile(scope.getSimpleName(), css.media());
      }

      String path = Strings.isEmpty(css.path()) ? getDefaultCssPath(css.media()) : css.path();
      SortedSet<WeightedResourceSpec> specs = contributions.get(path);
      if (specs == null) {
        specs = new TreeSet<WeightedResourceSpec>(WeightedResourceSpecComparator.INSTANCE);
        contributions.put(path, specs);
      }
      if (!specs.add(new WeightedResourceSpec(scope, file, css.order()))) {
        throw new WicketRuntimeException("duplicate resource contribution: " + css + ", scope=" + scope);
      }
    }
  }

  static String getDefaultCssFile(String simpleName, String media) {
    if (!Strings.isEmpty(media) && !"all".equals(media)) {
      return simpleName + "-" + media + ".css";
    }
    return simpleName + ".css";
  }

  static String getDefaultCssPath(String media) {
    if (!Strings.isEmpty(media)) {
      return media + ".css";
    }
    return DEFAULT_PATH_CSS;
  }

  private void addResourceContributions(Class<?> scope, ResourceContribution resource,
      Map<String, SortedSet<WeightedResourceSpec>> contributions) {
    for (String file : resource.value()) {
      if (Strings.isEmpty(file)) {
        throw new WicketRuntimeException("empty file name not allowed for @ResourceContributions at class "
            + scope.getName());
      }

      // don't merge resources by default
      String path = Strings.isEmpty(resource.path()) ? file : resource.path();
      SortedSet<WeightedResourceSpec> specs = contributions.get(path);
      if (specs == null) {
        specs = new TreeSet<WeightedResourceSpec>(WeightedResourceSpecComparator.INSTANCE);
        contributions.put(path, specs);
      }
      if (!specs.add(new WeightedResourceSpec(scope, file))) {
        throw new WicketRuntimeException("duplicate resource contribution: " + resource + ", scope=" + scope);
      }
    }
  }

  /**
   * @return an unmodifiable map of contributions mapped by scope
   */
  public Map<String, SortedSet<WeightedResourceSpec>> getContributions() {
    return _contributions;
  }

  /**
   * Get the Spring search pattern given a package name or part of a package
   * name
   *
   * @param packageName
   *            a package name
   * @return a Spring search pattern for the given package
   */
  private String getPatternForPackage(String packageName) {
    if (packageName == null) {
      packageName = "";
    }
    packageName = packageName.replace('.', '/');
    if (!packageName.endsWith("/")) {
      packageName += '/';
    }

    return "classpath*:" + packageName + "**/*.class";
  }

  @SuppressWarnings(value = "EQ_DOESNT_OVERRIDE_EQUALS", justification = "super type is sufficient, ignore weight")
  public static final class WeightedResourceSpec extends ResourceSpec {

    private static final long serialVersionUID = 1L;

    private final int _weight;

    public WeightedResourceSpec(Class<?> scope, String file, int weight) {
      super(scope, file);
      _weight = weight;
    }

    public WeightedResourceSpec(Class<?> scope, String file) {
      this(scope, file, 0);
    }

    @Override
    public String toString() {
      return super.toString() + " (weight=" + _weight + ")";
    }
  }

  public enum WeightedResourceSpecComparator implements Comparator<WeightedResourceSpec> {
    INSTANCE;

    @Override
    public int compare(WeightedResourceSpec o1, WeightedResourceSpec o2) {
      if (o1 == null) {
        return o2 == null ? 0 : -1;
      } else if (o2 == null) {
        return 1;
      }
      if (o1.equals(o2)) {
        return 0;
      }

      // from highest to lowest - avoid overflow
      int val = Integer.valueOf(o2._weight).compareTo(o1._weight);
      if (val != 0) {
        return val;
      }
      val = o1.getFile().compareTo(o2.getFile());
      if (val != 0) {
        return val;
      }
      return o1.getScope().getName().compareTo(o2.getScope().getName());
    }

  }
}
TOP

Related Classes of org.wicketstuff.mergedresources.annotations.ContributionScanner$WeightedResourceSpec

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.