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

hudson.model.Label Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *
 * Copyright (c) 2004-2010 Oracle Corporation.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *
 *    Kohsuke Kawaguchi, Tom Huybrechts
 *
 *
 *******************************************************************************/ 

package hudson.model;

import hudson.Util;
import static hudson.Util.fixNull;

import hudson.model.labels.LabelAtom;
import hudson.model.labels.LabelExpression;
import hudson.model.labels.LabelExpressionLexer;
import hudson.model.labels.LabelExpressionParser;
import hudson.model.labels.LabelOperatorPrecedence;
import hudson.slaves.NodeProvisioner;
import hudson.slaves.Cloud;
import hudson.util.QuotedStringTokenizer;
import hudson.util.VariableResolver;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Collection;
import java.util.TreeSet;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import hudson.matrix.Axis;
import hudson.matrix.MatrixProject;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;

/**
 * Group of {@link Node}s.
 *
 * @author Kohsuke Kawaguchi
 * @see Hudson#getLabels()
 * @see Hudson#getLabel(String)
 */
@ExportedBean
public abstract class Label extends Actionable implements Comparable

This excludes executors that belong to offline nodes. */ @Exported public int getTotalExecutors() { int r = 0; for (Node n : getNodes()) { Computer c = n.toComputer(); if (c != null && c.isOnline()) { r += c.countExecutors(); } } return r; } /** * Number of busy {@link Executor}s that are carrying out some work right * now. */ @Exported public int getBusyExecutors() { int r = 0; for (Node n : getNodes()) { Computer c = n.toComputer(); if (c != null && c.isOnline()) { r += c.countBusy(); } } return r; } /** * Number of idle {@link Executor}s that can start working immediately. */ @Exported public int getIdleExecutors() { int r = 0; for (Node n : getNodes()) { Computer c = n.toComputer(); if (c != null && (c.isOnline() || c.isConnecting())) { r += c.countIdle(); } } return r; } /** * Returns true if all the nodes of this label is offline. */ @Exported public boolean isOffline() { for (Node n : getNodes()) { if (n.toComputer() != null && !n.toComputer().isOffline()) { return false; } } return true; } /** * Returns a human readable text that explains this label. */ @Exported public String getDescription() { Set nodes = getNodes(); if (nodes.isEmpty()) { Set clouds = getClouds(); if (clouds.isEmpty()) { return Messages.Label_InvalidLabel(); } return Messages.Label_ProvisionedFrom(toString(clouds)); } if (nodes.size() == 1) { return nodes.iterator().next().getNodeDescription(); } return Messages.Label_GroupOf(toString(nodes)); } private String toString(Collection model) { boolean first = true; StringBuilder buf = new StringBuilder(); for (ModelObject c : model) { if (buf.length() > 80) { buf.append(",..."); break; } if (!first) { buf.append(','); } else { first = false; } buf.append(c.getDisplayName()); } return buf.toString(); } /** * Returns projects that are tied on this node. */ @Exported public List getTiedJobs() { List r = new ArrayList(); for (AbstractProject p : Util.filter(Hudson.getInstance().getItems(), AbstractProject.class)) { if (this.equals(p.getAssignedLabel())) { r.add(p); } } for (MatrixProject p : Util.filter(Hudson.getInstance().getItems(), MatrixProject.class)) { for (Axis axis : p.getAxes()) { if (axis.getValues().contains(getName())){ r.add(p); } } } return r; } public boolean contains(Node node) { return getNodes().contains(node); } /** * If there's no such label defined in {@link Node} or {@link Cloud}. This * is usually used as a signal that this label is invalid. */ public boolean isEmpty() { return getNodes().isEmpty() && getClouds().isEmpty(); } /*package*/ void reset() { nodes = null; clouds = null; } /** * Expose this object to the remote API. */ public Api getApi() { return new Api(this); } /** * Returns the label that represents "this&rhs" */ public Label and(Label rhs) { return new LabelExpression.And(this, rhs); } /** * Returns the label that represents "this|rhs" */ public Label or(Label rhs) { return new LabelExpression.Or(this, rhs); } /** * Returns the label that represents "this<->rhs" */ public Label iff(Label rhs) { return new LabelExpression.Iff(this, rhs); } /** * Returns the label that represents "this->rhs" */ public Label implies(Label rhs) { return new LabelExpression.Implies(this, rhs); } /** * Returns the label that represents "!this" */ public Label not() { return new LabelExpression.Not(this); } /** * Returns the label that represents "(this)" This is a pointless operation * for machines, but useful for humans who find the additional parenthesis * often useful */ public Label paren() { return new LabelExpression.Paren(this); } /** * Precedence of the top most operator. */ public abstract LabelOperatorPrecedence precedence(); @Override public boolean equals(Object that) { if (this == that) { return true; } if (that == null || getClass() != that.getClass()) { return false; } return name.equals(((Label) that).name); } @Override public int hashCode() { return name.hashCode(); } public int compareTo(Label that) { return this.name.compareTo(that.name); } @Override public String toString() { return name; } public static final class ConverterImpl implements Converter { public ConverterImpl() { } public boolean canConvert(Class type) { return Label.class.isAssignableFrom(type); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { Label src = (Label) source; writer.setValue(src.getExpression()); } public Object unmarshal(HierarchicalStreamReader reader, final UnmarshallingContext context) { return Hudson.getInstance().getLabel(reader.getValue()); } } /** * Convers a whitespace-separate list of tokens into a set of * {@link Label}s. * * @param labels Strings like "abc def ghi". Can be empty or null. * @return Can be empty but never null. A new writable set is always * returned, so that the caller can add more to the set. * @since 1.308 */ public static Set parse(String labels) { Set r = new TreeSet(); labels = fixNull(labels); if (labels.length() > 0) { for (String l : new QuotedStringTokenizer(labels).toArray()) { r.add(Hudson.getInstance().getLabelAtom(l)); } } return r; } /** * Obtains a label by its {@linkplain #getName() name}. */ public static Label get(String l) { return Hudson.getInstance().getLabel(l); } /** * Parses the expression into a label expression tree. * * TODO: replace this with a real parser later */ public static Label parseExpression(String labelExpression) throws RecognitionException { LabelExpressionLexer lexer = new LabelExpressionLexer(new ANTLRStringStream(labelExpression)); return new LabelExpressionParser(new CommonTokenStream(lexer)).expr(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy