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

com.redhat.ceylon.model.loader.OsgiVersion Maven / Gradle / Ivy

There is a newer version: 1.3.3
Show newest version
package com.redhat.ceylon.model.loader;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class OsgiVersion {
    private static HashMap ceylonQualifiers;
    static {
        ceylonQualifiers = new HashMap();
        ceylonQualifiers.put("alpha", 0);
        ceylonQualifiers.put("a", 0);
        ceylonQualifiers.put("beta", 1);
        ceylonQualifiers.put("b", 1);
        ceylonQualifiers.put("milestone", 2);
        ceylonQualifiers.put("m", 2);
        ceylonQualifiers.put("rc", 3);
        ceylonQualifiers.put("cr", 3);
        ceylonQualifiers.put("snapshot", 4);
        ceylonQualifiers.put("ga", 5);
        ceylonQualifiers.put("final", 5);
        ceylonQualifiers.put("sp", 6);
    }
    private static int QUALIFIER_OTHER = 7; // Same as the size of the above list
    
    public static final SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd-HHmm");
    static {
        formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
    }

    public static interface ErrorReporter {
        void reportError(String errorMessage, Throwable optionalThrowable);
    }
    
    public static String withTimestamp(String osgiVersion, String formattedDateInGmt) {
        return withTimestamp(osgiVersion, formattedDateInGmt, null);
    }

    public static String withTimestamp(String osgiVersion, String formattedDateInGmt, ErrorReporter errorReporter) {
        Date date;
        try {
            date = formatter.parse(formattedDateInGmt);
        } catch (ParseException e) {
            String errorMessage = "The provided OSGI qualifier timestamp cannot be parsed. The current date will be used instead.";
            if (errorReporter != null) {
                errorReporter.reportError(errorMessage, e);
            } else {
                System.err.println("ERROR: " + errorMessage);
            }
            date = new Date();
        }
        return withTimestamp(osgiVersion, date);
    }
    
    public static String withTimestamp(String osgiVersion) {
        return withTimestamp(osgiVersion, new Date());
    }
    
    public static String withTimestamp(String osgiVersion, Date date) {
        return osgiVersion + "-" + formatter.format(date);
    }
    
    public static String fromCeylonVersion(String ceylonVersion) {
        // Insert a "." between digits and letters
        StringBuffer buf = new StringBuffer();
        Pattern p = Pattern.compile("\\d\\pL|\\pL\\d");
        Matcher m = p.matcher(ceylonVersion);
        while (m.find()) {
            String found = m.group();
            assert(found.length() == 2);
            m.appendReplacement(buf, found.charAt(0) + "." + found.charAt(1));
        }
        m.appendTail(buf);
        
        // Split on dots and dashes
        String[] versionParts = buf.toString().split("[\\.-]");

        // Now iterator over all the parts applying the following rules:
        // - any empty part is treated as "0"
        // - any number in the first 3 positions are added as-is
        // - any number after that gets padded with leading zeros to a length of 3 and prefixed with the letter "n"
        // - when a non-number is encountered in the first 3 positions enough "0" parts are added to have at least 3 numbers at the start
        // - a non-number gets lookup in the qualifier table and if found replaced by its index
        // - when not found we add the part prefixed with the size of the qualifier table and a dash
        boolean inOsgiQualifier = false;
        boolean lastWasQualifier = false;
        ArrayList resultParts = new ArrayList();
        for (int i = 0; i < versionParts.length; i++) {
            String part = versionParts[i];
            if (part.isEmpty()) {
                part = "0";
            }
            inOsgiQualifier = inOsgiQualifier || i >= 3;
            if (isNumber(part)) {
                if (inOsgiQualifier) {
                    part = String.format("n%03d", Integer.parseInt(part));
                }
                lastWasQualifier = false;
            } else {
                if (!inOsgiQualifier) {
                    // We need our version to start with at least 3 numbers
                    for (int j = i; j < 3; j++) {
                        resultParts.add("0");
                    }
                    inOsgiQualifier = true;
                }
                Integer idx = ceylonQualifiers.get(part.toLowerCase());
                if (idx != null) {
                    part = idx.toString();
                } else {
                    part = QUALIFIER_OTHER + "-" + part;
                }
                lastWasQualifier = true;
            }
            resultParts.add(part);
        }
        // We need our version to start with at least 3 numbers
        for (int j = resultParts.size(); j < 3; j++) {
            resultParts.add("0");
            lastWasQualifier = false;
        }
        
        if (!lastWasQualifier) {
            // If we didn't terminate with a qualifier let's treat as if it was "final"
            resultParts.add(ceylonQualifiers.get("final").toString());
        }
        
        // Now join all the resulting parts together. The first 4
        // elements get separated by dots, the rest by dashes and the
        // qualifier always starts with 'osgi-'
        StringBuffer result = new StringBuffer();
        for (int i=0; i < resultParts.size(); i++) {
            String part = resultParts.get(i);
            if (i > 3) {
                result.append("-");
            } else if (i > 0) {
                result.append(".");
            }
            if (i == 3) {
                result.append("osgi-");
            }
            result.append(part);
        }
        
        return result.toString();
    }

    private static boolean isNumber(String txt) {
        return txt.matches("\\d+");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy