/*
* RHQ Management Platform
* Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.enterprise.server.plugins.packagetypeCli;
import java.util.Comparator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.PackageVersionFormatDescription;
import org.rhq.core.domain.content.ValidatablePackageDetailsKey;
import org.rhq.core.domain.util.OSGiVersion;
import org.rhq.core.domain.util.OSGiVersionComparator;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.content.AbstractPackageTypeBehavior;
import org.rhq.enterprise.server.plugin.pc.content.PackageDetailsValidationException;
/**
* This plugin defines the version formatting of the server-side CLI package type.
*
* In order for the CLI packages to exist per user, the format of the version has to include
* the username.
*
* The format is therefore following:
*
* {username}:{osgi.version.string}
*
* @author Lukas Krejci
*/
public class CliPackageTypeBehavior extends AbstractPackageTypeBehavior<ServerPluginComponent> {
private static final Log LOG = LogFactory.getLog(CliPackageTypeBehavior.class);
private static final String FULL_VERSION_REGEX = "^([^:]+:)?\\d+(\\.\\d+(\\.\\d+(\\..*)?)?)?$";
private static final String OSGI_EXTRACT_REGEX = "^([^:]+:)?(\\d+(\\.\\d+(\\.\\d+(\\..*)?)?)?)$";
private static final int OSGI_EXTRACT_VERSION_GROUP = 2;
private static final String PACKAGETYPE_NAME = "org.rhq.enterprise.server.plugins.packagetypeCli.SERVER_SIDE_CLI_SCRIPT";
private static final Comparator<PackageVersion> VERSION_COMPARATOR = new Comparator<PackageVersion>() {
private final OSGiVersionComparator OSGI_COMPARATOR = new OSGiVersionComparator();
public int compare(PackageVersion o1, PackageVersion o2) {
String v1 = o1.getVersion();
String v2 = o2.getVersion();
if (v1 != null && v2 != null) {
String[] v1Parts = getVersionParts(v1);
String[] v2Parts = getVersionParts(v2);
if (v1Parts[1] != null && v2Parts[1] != null) {
try {
return OSGI_COMPARATOR.compare(v1Parts[1], v2Parts[1]);
} catch (IllegalArgumentException e) {
//well.. they don't look like OSGi versions
}
}
}
//as a fallback, compare by ID. But we're enforcing the format in the validate
//method so this shouldn't ever happen.
LOG.warn("Using a fallback version comparison on package versions " + o1 + " and " + o2 + ". This should not happen.");
return Integer.valueOf(o1.getId()).compareTo(o2.getId());
}
};
public Comparator<PackageVersion> getPackageVersionComparator(String packageTypeName) {
if (PACKAGETYPE_NAME.equals(packageTypeName)) {
return VERSION_COMPARATOR;
}
return null;
}
public void validateDetails(ValidatablePackageDetailsKey key, Subject origin)
throws PackageDetailsValidationException {
key.setVersion(reformatVersion(key.getVersion(), origin.getName()));
}
public PackageVersionFormatDescription getPackageVersionFormat(String packageTypeName) {
if (PACKAGETYPE_NAME.equals(packageTypeName)) {
return new PackageVersionFormatDescription(FULL_VERSION_REGEX, OSGI_EXTRACT_REGEX, OSGI_EXTRACT_VERSION_GROUP, null);
}
return null;
}
private static String reformatVersion(String version, String userName) throws PackageDetailsValidationException {
String[] parts = getVersionParts(version);
if (!OSGiVersion.isValid(parts[1])) {
//ok the user supplied something that isn't an OSGi version.
//We can't accept that.
throw new PackageDetailsValidationException("The version part of '" + version + "' isn't an OSGi version string.");
}
return userName + ":" + parts[1];
}
private static String[] getVersionParts(String version) {
String[] ret = new String[2];
int colonIdx = version.indexOf(':');
if (colonIdx >= 0 && colonIdx < version.length() - 1) {
ret[0] = version.substring(0, colonIdx);
ret[1] = version.substring(colonIdx + 1);
} else {
ret[1] = version;
}
return ret;
}
}