
hudson.matrix.Layouter Maven / Gradle / Ivy
Show all versions of hudson-core Show documentation
/*******************************************************************************
*
* Copyright (c) 2004-2009 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
*
*
*******************************************************************************/
package hudson.matrix;
import java.util.List;
import java.util.ArrayList;
import java.util.AbstractList;
import java.util.Map;
import java.util.HashMap;
/**
* Used to assist thegeneration of config table.
*
*
* {@link Axis Axes} are split into four groups.
* {@link #x Ones that are displayed as columns},
* {@link #y Ones that are displayed as rows},
* {@link #z Ones that are listed as bullet items inside table cell},
* and those which only have one value, and therefore doesn't show up
* in the table.
*
*
* Because of object reuse inside {@link Layouter}, this class is not thread-safe.
*
* @author Kohsuke Kawaguchi
*/
public abstract class Layouter {
public final List x,y,z;
/**
* Axes that only have one value.
*/
private final List trivial = new ArrayList();
/**
* Number of data columns and rows.
*/
private int xSize, ySize, zSize;
public Layouter(List x, List y, List z) {
this.x = x;
this.y = y;
this.z = z;
init();
}
/**
* Automatically split axes to x,y, and z.
*/
public Layouter(AxisList axisList) {
x = new ArrayList();
y = new ArrayList();
z = new ArrayList();
List nonTrivialAxes = new ArrayList();
for (Axis a : axisList) {
if(a.size()>1)
nonTrivialAxes.add(a);
else
trivial.add(a);
}
switch(nonTrivialAxes.size()) {
case 0:
break;
case 1:
z.add(nonTrivialAxes.get(0));
break;
case 2:
// use the longer axis in Y
Axis a = nonTrivialAxes.get(0);
Axis b = nonTrivialAxes.get(1);
x.add(a.size() > b.size() ? b : a);
y.add(a.size() > b.size() ? a : b);
break;
default:
// for size > 3, use x and y, and try to pack y more
for( int i=0; i=0; n-- )
w *= x.get(n).size();
return w;
}
/**
* Computes the width of n-th Y-axis.
*/
public int height(int n) {
return calc(y,n);
}
private int calc(List l, int n) {
int w = 1;
for( n++ ; n getRows() {
return new AbstractList() {
final Row row = new Row();
public Row get(int index) {
row.index = index;
return row;
}
public int size() {
return ySize;
}
};
}
/**
* Represents a row, which is a collection of {@link Column}s.
*/
public final class Row extends AbstractList {
private int index;
final Column col = new Column();
@Override
public Column get(int index) {
col.xp = index;
col.yp = Row.this.index;
return col;
}
@Override
public int size() {
return xSize;
}
public String drawYHeader(int n) {
int base = calc(y,n);
if(index/base==(index-1)/base && index!=0) return null; // no need to draw a new value
Axis axis = y.get(n);
return axis.value((index/base)%axis.values.size());
}
}
protected abstract T getT(Combination c);
public final class Column extends AbstractList {
/**
* Cell position.
*/
private int xp,yp;
private final Map m = new HashMap();
public T get(int zp) {
m.clear();
buildMap(xp,x);
buildMap(yp,y);
buildMap(zp,z);
for (Axis a : trivial)
m.put(a.name,a.value(0));
return getT(new Combination(m));
}
private void buildMap(int p, List axes) {
int n = p;
for( int i= axes.size()-1; i>=0; i-- ) {
Axis a = axes.get(i);
m.put(a.name, a.value(n%a.size()));
n /= a.size();
}
}
public int size() {
return zSize;
}
}
}