package org.simantics.scl.reflection; import java.net.URL; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.internal.runtime.PlatformActivator; import org.osgi.framework.Bundle; import org.osgi.framework.Version; public class OntologyVersions { private static final boolean PRINT = false; private static OntologyVersions INSTANCE; private final Pattern versionExtractPattern = Pattern.compile("^.*-(\\d+\\.\\d+)"); private Map unversionedToCurrent = new HashMap(); private Map currentToUnversioned = new HashMap(); final private Pattern unversionedPattern; final private Pattern currentPattern; private OntologyVersions() { Map versions = new HashMap(); if(PRINT) System.err.println("== Ontology report =="); for(Bundle bundle : PlatformActivator.getContext().getBundles()) { URL url = bundle.getEntry("graph.tg"); if (url==null) continue; try { String name = (String) bundle.getHeaders().get("Bundle-Name"); Version osgiVersion = bundle.getVersion(); Version previous = versions.get(name); if(previous == null || osgiVersion.compareTo(previous) > 0) versions.put(name, osgiVersion); if(PRINT) System.err.println("found: " + name + ":" + osgiVersion); } finally { } } for(Map.Entry entry : versions.entrySet()) { int minor = entry.getValue().getMinor(); int major = entry.getValue().getMajor(); String unversioned = entry.getKey() + "-0.0"; String versioned = entry.getKey() + "-" + major + "." + minor; unversionedToCurrent.put(unversioned, versioned); currentToUnversioned.put(versioned, unversioned); if(PRINT) System.err.println("latest: " + versioned); } if(PRINT) System.err.println("== Ontology report ends =="); unversionedPattern = Pattern.compile("(" + joinKeys(unversionedToCurrent) + ")"); currentPattern = Pattern.compile("(" + joinKeys(currentToUnversioned) + ")"); } public static OntologyVersions getInstance() { if(INSTANCE == null) { INSTANCE = new OntologyVersions(); } return INSTANCE; } private String joinKeys(Map tokens) { Collection keys = tokens.keySet(); StringBuilder b = new StringBuilder(); boolean first = true; for(String key : keys) { if(!first) b.append("|"); first = false; b.append(key); } return b.toString(); } /* * Replaces all references to URIs with unversioned ontologies with current versions * e.g. http://www.simantics.org/Layer0-0.0 => http://www.simantics.org/Layer0-1.0 * * @param text Any string */ public String currentVersion(String text) { Matcher matcher = unversionedPattern.matcher(text); StringBuffer sb = new StringBuffer(text.length()); while(matcher.find()) { matcher.appendReplacement(sb, unversionedToCurrent.get(matcher.group(1))); } matcher.appendTail(sb); return sb.toString(); } /* * Replaces all references to URIs from current ontologies with unversioned ones * e.g. http://www.simantics.org/Layer0-1.0 => http://www.simantics.org/Layer0-0.0 * * @param text Any string */ public String unversioned(String text) { Matcher matcher = currentPattern.matcher(text); StringBuffer sb = new StringBuffer(text.length()); while(matcher.find()) { matcher.appendReplacement(sb, currentToUnversioned.get(matcher.group(1))); } matcher.appendTail(sb); return sb.toString(); } /** * Calculates the current version of the specified version-agnostic URI and * returns only the version part. * e.g. http://www.simantics.org/Layer0-0.0 => 1.1 * * @param text Any string */ public String currentOntologyVersion(String ontologyURI) { String versionedURI = currentVersion(ontologyURI); Matcher m = versionExtractPattern.matcher(versionedURI); if (!m.matches()) throw new IllegalArgumentException("Cannot extract version from ontology URI '" + ontologyURI + "' with pattern " + versionExtractPattern.pattern()); return m.group(1); } }