Package org.geomajas.spring

Source Code of org.geomajas.spring.DependencyCheckPostProcessor$Version

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.spring;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.geomajas.global.ExceptionCode;
import org.geomajas.global.GeomajasException;
import org.geomajas.global.PluginInfo;
import org.geomajas.global.PluginVersionInfo;
import org.geomajas.service.TestRecorder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
* Spring configuration post-processor which verifies that all registered plug-ins (including the back-end), have their
* their declared dependency requirements met.
*
* @author Joachim Van der Auwera
*/
@Component
public class DependencyCheckPostProcessor {

  protected static final String GROUP = "depcheck";
  protected static final String VALUE = "done";

  private static final String EXPR_START = "$";

  @Autowired(required = false)
  protected Map<String, PluginInfo> declaredPlugins;

  @Autowired
  private TestRecorder recorder;

  @PostConstruct
  protected void checkPluginDependencies() throws GeomajasException {
    if ("true".equals(System.getProperty("skipPluginDependencyCheck"))) {
      return;
    }

    if (null == declaredPlugins) {
      return;
    }

    // start by going through all plug-ins to build a map of versions for plug-in keys
    // includes verification that each key is only used once
    Map<String, String> versions = new HashMap<String, String>();
    for (PluginInfo plugin : declaredPlugins.values()) {
      String name = plugin.getVersion().getName();
      String version = plugin.getVersion().getVersion();
      // check for multiple plugin with same name but different versions (duplicates allowed for jar+source dep)
      if (null != version) {
        String otherVersion = versions.get(name);
        if (null != otherVersion) {
          if (!version.startsWith(EXPR_START)) {
            if (!otherVersion.startsWith(EXPR_START) && !otherVersion.equals(version)) {
              throw new GeomajasException(ExceptionCode.DEPENDENCY_CHECK_INVALID_DUPLICATE,
                  name, version, versions.get(name));
            }
            versions.put(name, version);
          }
        } else {
          versions.put(name, version);
        }
      }
    }

    // Check dependencies
    StringBuilder message = new StringBuilder();
    String backendVersion = versions.get("Geomajas");
    for (PluginInfo plugin : declaredPlugins.values()) {
      String name = plugin.getVersion().getName();
      message.append(checkVersion(name, "Geomajas back-end", plugin.getBackendVersion(), backendVersion));
      List<PluginVersionInfo> dependencies = plugin.getDependencies();
      if (null != dependencies) {
        for (PluginVersionInfo dependency : plugin.getDependencies()) {
          String depName = dependency.getName();
          message.append(checkVersion(name, depName, dependency.getVersion(), versions.get(depName)));
        }
      }
      dependencies = plugin.getOptionalDependencies();
      if (null != dependencies) {
        for (PluginVersionInfo dependency : dependencies) {
          String depName = dependency.getName();
          String availableVersion = versions.get(depName);
          if (null != availableVersion) {
            message.append(checkVersion(name, depName, dependency.getVersion(), versions.get(depName)));
          }
        }
      }
    }
    if (message.length() > 0) {
      throw new GeomajasException(ExceptionCode.DEPENDENCY_CHECK_FAILED, message.toString());
    }

    recorder.record(GROUP, VALUE);
  }

  String checkVersion(String pluginName, String dependency, String requestedVersion, String availableVersion) {
    if (null == availableVersion) {
      return "Dependency " + dependency + " not found for " + pluginName + ", version " + requestedVersion +
          " or higher needed.\n";
    }
    if (requestedVersion.startsWith(EXPR_START) || availableVersion.startsWith(EXPR_START)) {
      return "";
    }
    Version requested = new Version(requestedVersion);
    Version available = new Version(availableVersion);
    if (requested.getMajor() != available.getMajor()) {
      return "Dependency " + dependency + " is provided in a incompatible API version for plug-in " +
          pluginName + ", which requests version " + requestedVersion +
          ", but version " + availableVersion + " supplied.\n";
    }
    if (requested.after(available)) {
      return "Dependency " + dependency + " too old for " + pluginName + ", version " + requestedVersion +
          " or higher needed, but version " + availableVersion + " supplied.\n";
    }
    return "";
  }

  /** Parsed version representation. */
  public static class Version {

    private int major, minor, revision;
    private String qualifier;

    public Version(String version) {
      int pos;
      String part;

      pos = getSeparatorPosition(version);
      part = version.substring(0, pos);
      version = getRest(version, pos);
      try {
        major = Integer.parseInt(part);
      } catch (NumberFormatException nfe) {
        qualifier = part;
        return;
      }
      pos = getSeparatorPosition(version);
      part = version.substring(0, pos);
      version = getRest(version, pos);
      try {
        minor = Integer.parseInt(part);
      } catch (NumberFormatException nfe) {
        qualifier = part;
        return;
      }
      pos = getSeparatorPosition(version);
      part = version.substring(0, pos);
      version = getRest(version, pos);
      try {
        revision = Integer.parseInt(part);
      } catch (NumberFormatException nfe) {
        qualifier = part;
        return;
      }
      qualifier = version;
    }

    private int getSeparatorPosition(String str) {
      int pos1 = str.indexOf('.');
      int pos2 = str.indexOf('-');
      if (pos1 >= 0) {
        if (pos2 >= 0) {
          return Math.min(pos1, pos2);
        }
        return pos1;
      }
      if (pos2 >= 0) {
        return pos2;
      }
      return str.length();
    }

    private String getRest(String str, int pos) {
      if (str.length() > pos) {
        return str.substring(pos + 1);
      }
      return "";
    }

    public boolean after(Version other) {
      if (major > other.major) {
        return true;
      }
      if (major == other.major && minor > other.minor) {
        return true;
      }
      if (major == other.major && minor == other.minor && revision > other.revision) {
        return true;
      }
      if (major == other.major && minor == other.minor && revision == other.revision) {
        return qualifier.compareTo(other.qualifier) < 0;
      }
      return false;
    }

    public int getMajor() {
      return major;
    }

    public int getMinor() {
      return minor;
    }

    public int getRevision() {
      return revision;
    }

    public String getQualifier() {
      return qualifier;
    }
  }
}
TOP

Related Classes of org.geomajas.spring.DependencyCheckPostProcessor$Version

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.