/* * The MIT License * * Copyright 2011 Sony Ericsson Mobile Communications. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.sonyericsson.hudson.plugins.metadata.cli; import com.sonyericsson.hudson.plugins.metadata.model.MetadataBuildAction; import com.sonyericsson.hudson.plugins.metadata.model.MetadataContainer; import com.sonyericsson.hudson.plugins.metadata.model.MetadataJobProperty; import com.sonyericsson.hudson.plugins.metadata.model.MetadataNodeProperty; import com.sonyericsson.hudson.plugins.metadata.model.values.MetadataValue; import hudson.model.AbstractProject; import hudson.model.Hudson; import hudson.model.Node; import hudson.model.Run; import hudson.model.TopLevelItem; import hudson.slaves.NodeProperty; import hudson.slaves.NodePropertyDescriptor; import hudson.util.DescribableList; import org.kohsuke.args4j.CmdLineException; import java.io.IOException; import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static java.net.HttpURLConnection.HTTP_OK; /** * Common utility functions for the CLI commands. * * @author Robert Sandell <robert.sandell@sonyericsson.com> */ public abstract class CliUtils { /** * Status codes to be returned from the cli commands. */ public static enum Status { /** * Commandline status code indicating {@link NoItemException}. (-1) */ ERR_NO_ITEM(-1, HTTP_NOT_FOUND), /** * Commandline status code indicating {@link NoMetadataException}. (-2) */ ERR_NO_METADATA(-2, HTTP_NOT_FOUND), /** * Commandline status code indicating illegal commandline argument combinations. (1) */ ERR_BAD_CMD(1, HTTP_BAD_REQUEST), /** * Commandline status code indicating a * {@link com.sonyericsson.hudson.plugins.metadata.model.JsonUtils.ParseException}. * (2) */ ERR_BAD_DATA(2, HTTP_BAD_REQUEST), /** * Commandline status indicating that the metadata could not be saved to disk. */ WARN_NO_SAVE(10, HTTP_OK); private final int code; private final int httpStatus; /** * Constructor. * * @param code the error code. * @param httpStatus the HTTP status to set in the response. * @see #code() */ Status(int code, int httpStatus) { this.code = code; this.httpStatus = httpStatus; } /** * The error code to return from the command. * * @return the error code. */ public int code() { return code; } /** * The HTTP status that should be set in the HTTP response if any. * @return the status code. */ public int httpStatus() { return httpStatus; } } /** * Finds the container that has been selected on the commandline. * * @param node the node parameter. * @param job the job parameter * @param build the build parameter * @param createContainer create the container when it doesn't exist instead of failing, if the specified item * doesn't exist it will still fail.. * @return the container if one is found. * * @throws CmdLineException if the combination of arguments are bad. * @throws NoItemException if the requested item (node, job or build) couldn't be found. * @throws NoMetadataException if the item doesn't contain any metadata. * @throws java.io.IOException if a metadata container needed to be added and it failed to do so. */ //CS IGNORE RedundantThrows FOR NEXT 3 LINES. REASON: NometadataException listed twice but it's not. public static MetadataContainer<MetadataValue> getContainer(String node, String job, Integer build, boolean createContainer) throws CmdLineException, NoItemException, NoMetadataException, IOException { if ((node == null || node.isEmpty()) && (job == null || job.isEmpty())) { throw new CmdLineException(null, "You must provide either a job or a node."); } if (build != null && (job == null || job.isEmpty())) { throw new CmdLineException(null, "You must provide a job for this build."); } MetadataContainer<MetadataValue> container = null; if (node != null && !node.isEmpty()) { Node theNode = Hudson.getInstance().getNode(node); if (theNode == null) { throw new NoItemException("No node with the name " + node + " exists on this server."); } DescribableList<NodeProperty<?>, NodePropertyDescriptor> properties = theNode.getNodeProperties(); if (properties == null) { throw new NoMetadataException("The node " + node + " has no associated properties."); } MetadataNodeProperty property = properties.get(MetadataNodeProperty.class); if (property != null) { container = property; } else { if (createContainer) { container = MetadataNodeProperty.MetadataNodePropertyDescriptor.instanceFor(theNode); } else { throw new NoMetadataException("The node " + node + " has no associated metadata."); } } } else if (job != null && !job.isEmpty()) { TopLevelItem item = Hudson.getInstance().getItem(job); if (item != null && item instanceof AbstractProject) { AbstractProject project = (AbstractProject)item; if (build != null && build >= 0) { Run buildByNumber = project.getBuildByNumber(build); if (buildByNumber != null) { MetadataBuildAction action = buildByNumber.getAction(MetadataBuildAction.class); if (action != null) { container = action; } else if (createContainer) { action = new MetadataBuildAction(); buildByNumber.addAction(action); container = action; } else { throw new NoMetadataException("Build #" + build + " of job " + job + " has no associated metadata."); } } else { throw new NoItemException("There is no build #" + build + " for job " + job); } } else { MetadataJobProperty property = (MetadataJobProperty)project.getProperty(MetadataJobProperty.class); if (property != null) { container = property; } else if (createContainer) { container = MetadataJobProperty.MetaDataJobPropertyDescriptor.instanceFor(project); } else { throw new NoMetadataException("Job " + job + " has no associated metadata."); } } } else { throw new NoItemException("No job with the name " + job + " exists on this server."); } } return container; } /** * Utility constructor. */ private CliUtils() { } /** * Exception thrown when the user has selected something that doesn't exist. */ public static class NoItemException extends Exception { /** * Default constructor. */ public NoItemException() { } /** * Standard Constructor. * * @param message the message. * @see Exception#Exception(String) */ public NoItemException(String message) { super(message); } /** * Standard Constructor. * * @param message the message. * @param cause the cause. * @see Exception#Exception(String, Throwable) */ public NoItemException(String message, Throwable cause) { super(message, cause); } /** * Standard Constructor. * * @param cause the cause. * @see Exception#Exception(Throwable) */ public NoItemException(Throwable cause) { super(cause); } } /** * Exception thrown when a user has selected something that doesn't have any metadata. */ public static class NoMetadataException extends Exception { /** * Default constructor. */ public NoMetadataException() { } /** * Standard Constructor. * * @param message the message. * @see Exception#Exception(String) */ public NoMetadataException(String message) { super(message); } /** * Standard Constructor. * * @param message the message. * @param cause the cause. * @see Exception#Exception(String, Throwable) */ public NoMetadataException(String message, Throwable cause) { super(message, cause); } /** * Standard Constructor. * * @param cause the cause. * @see Exception#Exception(Throwable) */ public NoMetadataException(Throwable cause) { super(cause); } } }