/* * 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; } }