text:
package com.mxgraph.canvas;

import java.awt.Font;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.mxgraph.util.mxBase64;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;

/**
 * An implementation of a canvas that uses SVG for painting. This canvas
 * ignores the STYLE_LABEL_BACKGROUNDCOLOR and
 * STYLE_LABEL_BORDERCOLOR styles due to limitations of SVG.
 */
public class mxSvgCanvas extends mxBasicCanvas
{

	/**
	 * Holds the HTML document that represents the canvas.
	 */
	protected Document document;

	/**
	 * Used internally for looking up elements. Workaround for getElementById
	 * not working.
	 */
	private Map<String, Element> gradients = new Hashtable<String, Element>();

	/**
	 * Used internally for looking up images.
	 */
	private Map<String, Element> images = new Hashtable<String, Element>();

	/**
	 *
	 */
	protected Element defs = null;

	/**
	 * Specifies if images should be embedded as base64 encoded strings.
	 * Default is false.
	 */
	protected boolean embedded = false;

	/**
	 * Constructs a new SVG canvas for the specified dimension and scale.
	 */
	public mxSvgCanvas()
	{
		this(null);
	}

	/**
	 * Constructs a new SVG canvas for the specified bounds, scale and
	 * background color.
	 */
	public mxSvgCanvas(Document document)
	{
		setDocument(document);
	}

	/**
	 *
	 */
	public void appendSvgElement(Element node)
	{
		if (document != null)
		{
			document.getDocumentElement().appendChild(node);
		}
	}

	/**
	 *
	 */
	protected Element getDefsElement()
	{
		if (defs == null)
		{
			defs = document.createElement("defs");

			Element svgNode = document.getDocumentElement();

			if (svgNode.hasChildNodes())
			{
				svgNode.insertBefore(defs, svgNode.getFirstChild());
			}
			else
			{
				svgNode.appendChild(defs);
			}
		}

		return defs;
	}

	/**
	 *
	 */
	public Element getGradientElement(String start, String end, String direction)
	{
		String id = getGradientId(start, end, direction);
		Element gradient = gradients.get(id);

		if (gradient == null)
		{
			gradient = createGradientElement(start, end, direction);
			gradient.setAttribute("id", "g" + (gradients.size() + 1));
			getDefsElement().appendChild(gradient);
			gradients.put(id, gradient);
		}

		return gradient;
	}

	/**
	 *
	 */
	public Element getGlassGradientElement()
	{
		String id = "mx-glass-gradient";

		Element glassGradient = gradients.get(id);

		if (glassGradient == null)
		{
			glassGradient = document.createElement("linearGradient");
			glassGradient.setAttribute("x1", "0%");
			glassGradient.setAttribute("y1", "0%");
			glassGradient.setAttribute("x2", "0%");
			glassGradient.setAttribute("y2", "100%");

			Element stop1 = document.createElement("stop");
			stop1.setAttribute("offset", "0%");
			stop1.setAttribute("style", "stop-color:#ffffff;stop-opacity:0.9");
			glassGradient.appendChild(stop1);

			Element stop2 = document.createElement("stop");
			stop2.setAttribute("offset", "100%");
			stop2.setAttribute("style", "stop-color:#ffffff;stop-opacity:0.1");
			glassGradient.appendChild(stop2);

			glassGradient.setAttribute("id", "g" + (gradients.size() + 1));
			getDefsElement().appendChild(glassGradient);
			gradients.put(id, glassGradient);
		}

		return glassGradient;
	}

	/**
	 *
	 */
	protected Element createGradientElement(String start, String end,
			String direction)
	{
		Element gradient = document.createElement("linearGradient");
		gradient.setAttribute("x1", "0%");
		gradient.setAttribute("y1", "0%");
		gradient.setAttribute("x2", "0%");
		gradient.setAttribute("y2", "0%");

		if (direction == null || direction.equals(mxConstants.DIRECTION_SOUTH))
		{
			gradient.setAttribute("y2", "100%");
		}
		else if (direction.equals(mxConstants.DIRECTION_EAST))
		{
			gradient.setAttribute("x2", "100%");
		}
		else if (direction.equals(mxConstants.DIRECTION_NORTH))
		{
			gradient.setAttribute("y1", "100%");
		}
		else if (direction.equals(mxConstants.DIRECTION_WEST))
		{
			gradient.setAttribute("x1", "100%");
		}

		Element stop = document.createElement("stop");
		stop.setAttribute("offset", "0%");
		stop.setAttribute("style", "stop-color:" + start);
		gradient.appendChild(stop);

		stop = document.createElement("stop");
		stop.setAttribute("offset", "100%");
		stop.setAttribute("style", "stop-color:" + end);
		gradient.appendChild(stop);

		return gradient;
	}

	/**
	 *
	 */
	public String getGradientId(String start, String end, String direction)
	{
		// Removes illegal characters from gradient ID
		if (start.startsWith("#"))
		{
			start = start.substring(1);
		}

		if (end.startsWith("#"))
		{
			end = end.substring(1);
		}

		// Workaround for gradient IDs not working in Safari 5 / Chrome 6
		// if they contain uppercase characters
		start = start.toLowerCase();
		end = end.toLowerCase();

		String dir = null;

		if (direction == null || direction.equals(mxConstants.DIRECTION_SOUTH))
		{
			dir = "south";
		}
		else if (direction.equals(mxConstants.DIRECTION_EAST))
		{
			dir = "east";
		}
		else
		{
			String tmp = start;
			start = end;
			end = tmp;

			if (direction.equals(mxConstants.DIRECTION_NORTH))
			{
				dir = "south";
			}
			else if (direction.equals(mxConstants.DIRECTION_WEST))
			{
				dir = "east";
			}
		}

		return "mx-gradient-" + start + "-" + end + "-" + dir;
	}

	/**
	 * Returns true if the given string ends with .png, .jpg or .gif.
	 */
	protected boolean isImageResource(String src)
	{
		return src != null
				&& (src.toLowerCase().endsWith(".png")
						|| src.toLowerCase().endsWith(".jpg") || src
						.toLowerCase().endsWith(".gif"));
	}

	/**
	 *
	 */
	protected InputStream getResource(String src)
	{
		InputStream stream = null;

		try
		{
			stream = new BufferedInputStream(new URL(src).openStream());
		}
		catch (Exception e1)
		{
			stream = getClass().getResourceAsStream(src);
		}

		return stream;
	}

	/**
	 * @throws IOException
	 *
	 */
	protected String createDataUrl(String src) throws IOException
	{
		String result = null;
		InputStream inputStream = isImageResource(src) ? getResource(src) : null;

		if (inputStream != null)
		{
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
			byte[] bytes = new byte[512];

			// Read bytes from the input stream in bytes.length-sized chunks and write
			// them into the output stream
			int readBytes;
			while ((readBytes = inputStream.read(bytes)) > 0)
			{
				outputStream.write(bytes, 0, readBytes);
			}

			// Convert the contents of the output stream into a Data URL
			String format = "png";
			int dot = src.lastIndexOf('.');

			if (dot > 0 && dot < src.length())
			{
				format = src.substring(dot + 1);
			}

			result = "data:image/"
					+ format
					+ ";base64,"
					+ mxBase64
							.encodeToString(outputStream.toByteArray(), false);
		}

		return result;
	}

	/**
	 *
	 */
	protected Element getEmbeddedImageElement(String src)
	{
		Element img = images.get(src);

		if (img == null)
		{
			img = document.createElement("svg");
			img.setAttribute("width", "100%");
			img.setAttribute("height", "100%");

			Element inner = document.createElement("image");
			inner.setAttribute("width", "100%");
			inner.setAttribute("height", "100%");

			// Store before transforming to DataURL
			images.put(src, img);

			if (!src.startsWith("data:image/"))
			{
				try
				{
					String tmp = createDataUrl(src);

					if (tmp != null)
					{
						src = tmp;
					}
				}
				catch (IOException e)
				{
					// ignore
				}
			}

			inner.setAttributeNS(mxConstants.NS_XLINK, "xlink:href", src);
			img.appendChild(inner);
			img.setAttribute("id", "i" + (images.size()));
			getDefsElement().appendChild(img);
		}

		return img;
	}

	/**
	 *
	 */
	protected Element createImageElement(double x, double y, double w,
			double h, String src, boolean aspect, boolean flipH, boolean flipV,
			boolean embedded)
	{
		Element elem = null;

		if (embedded)
		{
			elem = document.createElement("use");

			Element img = getEmbeddedImageElement(src);
			elem.setAttributeNS(mxConstants.NS_XLINK, "xlink:href",
					"#" + img.getAttribute("id"));
		}
		else
		{
			elem = document.createElement("image");

			elem.setAttributeNS(mxConstants.NS_XLINK, "xlink:href", src);
		}

		elem.setAttribute("x", String.valueOf(x));
		elem.setAttribute("y", String.valueOf(y));
		elem.setAttribute("width", String.valueOf(w));
		elem.setAttribute("height", String.valueOf(h));

		// FIXME: SVG element must be used for reference to image with
		// aspect but for images with no aspect this does not work.
		if (aspect)
		{
			elem.setAttribute("preserveAspectRatio", "xMidYMid");
		}
		else
		{
			elem.setAttribute("preserveAspectRatio", "none");
		}

		double sx = 1;
		double sy = 1;
		double dx = 0;
		double dy = 0;

		if (flipH)
		{
			sx *= -1;
			dx = -w - 2 * x;
		}

		if (flipV)
		{
			sy *= -1;
			dy = -h - 2 * y;
		}

		String transform = "";

		if (sx != 1 || sy != 1)
		{
			transform += "scale(" + sx + " " + sy + ") ";
		}

		if (dx != 0 || dy != 0)
		{
			transform += "translate(" + dx + " " + dy + ") ";
		}

		if (transform.length() > 0)
		{
			elem.setAttribute("transform", transform);
		}

		return elem;
	}

	/**
	 *
	 */
	public void setDocument(Document document)
	{
		this.document = document;
	}

	/**
	 * Returns a reference to the document that represents the canvas.
	 *
	 * @return Returns the document.
	 */
	public Document getDocument()
	{
		return document;
	}

	/**
	 *
	 */
	public void setEmbedded(boolean value)
	{
		embedded = value;
	}

	/**
	 *
	 */
	public boolean isEmbedded()
	{
		return embedded;
	}

	/*
	 * (non-Javadoc)
	 * @see com.mxgraph.canvas.mxICanvas#drawCell()
	 */
	public Object drawCell(mxCellState state)
	{
		Map<String, Object> style = state.getStyle();
		Element elem = null;

		if (state.getAbsolutePointCount() > 1)
		{
			List<mxPoint> pts = state.getAbsolutePoints();

			// Transpose all points by cloning into a new array
			pts = mxUtils.translatePoints(pts, translate.x, translate.y);

			// Draws the line
			elem = drawLine(pts, style);

			// Applies opacity
			float opacity = mxUtils.getFloat(style, mxConstants.STYLE_OPACITY,
					100);

			if (opacity != 100)
			{
				String value = String.valueOf(opacity / 100);
				elem.setAttribute("fill-opacity", value);
				elem.setAttribute("stroke-opacity", value);
			}
		}
		else
		{
			int x = (int) state.getX() + translate.x;
			int y = (int) state.getY() + translate.y;
			int w = (int) state.getWidth();
			int h = (int) state.getHeight();

			if (!mxUtils.getString(style, mxConstants.STYLE_SHAPE, "").equals(
					mxConstants.SHAPE_SWIMLANE))
			{
				elem = drawShape(x, y, w, h, style);
			}
			else
			{
				int start = (int) Math.round(mxUtils.getInt(style,
						mxConstants.STYLE_STARTSIZE,
						mxConstants.DEFAULT_STARTSIZE)
						* scale);

				// Removes some styles to draw the content area
				Map<String, Object> cloned = new Hashtable<String, Object>(
						style);
				cloned.remove(mxConstants.STYLE_FILLCOLOR);
				cloned.remove(mxConstants.STYLE_ROUNDED);

				if (mxUtils.isTrue(style, mxConstants.STYLE_HORIZONTAL, true))
				{
					elem = drawShape(x, y, w, start, style);
					drawShape(x, y + start, w, h - start, cloned);
				}
				else
				{
					elem = drawShape(x, y, start, h, style);
					drawShape(x + start, y, w - start, h, cloned);
				}
			}
		}

		return elem;
	}

	/*
	 * (non-Javadoc)
	 * @see com.mxgraph.canvas.mxICanvas#drawLabel()
	 */
	public Object drawLabel(String label, mxCellState state, boolean html)
	{
		mxRectangle bounds = state.getLabelBounds();

		if (drawLabels && bounds != null)
		{
			int x = (int) bounds.getX() + translate.x;
			int y = (int) bounds.getY() + translate.y;
			int w = (int) bounds.getWidth();
			int h = (int) bounds.getHeight();
			Map<String, Object> style = state.getStyle();

			return drawText(label, x, y, w, h, style);
		}

		return null;
	}

	/**
	 * Draws the shape specified with the STYLE_SHAPE key in the given style.
	 *
	 * @param x X-coordinate of the shape.
	 * @param y Y-coordinate of the shape.
	 * @param w Width of the shape.
	 * @param h Height of the shape.
	 * @param style Style of the the shape.
	 */
	public Element drawShape(int x, int y, int w, int h,
			Map<String, Object> style)
	{
		String fillColor = mxUtils.getString(style,
				mxConstants.STYLE_FILLCOLOR, "none");
		String gradientColor = mxUtils.getString(style,
				mxConstants.STYLE_GRADIENTCOLOR, "none");
		String strokeColor = mxUtils.getString(style,
				mxConstants.STYLE_STROKECOLOR, "none");
		float strokeWidth = (float) (mxUtils.getFloat(style,
				mxConstants.STYLE_STROKEWIDTH, 1) * scale);
		float opacity = mxUtils.getFloat(style, mxConstants.STYLE_OPACITY, 100);

		// Draws the shape
		String shape = mxUtils.getString(style, mxConstants.STYLE_SHAPE, "");
		Element elem = null;
		Element background = null;

		if (shape.equals(mxConstants.SHAPE_IMAGE))
		{
			String img = getImageForStyle(style);

			if (img != null)
			{
				// Vertical and horizontal image flipping
				boolean flipH = mxUtils.isTrue(style,
						mxConstants.STYLE_IMAGE_FLIPH, false);
				boolean flipV = mxUtils.isTrue(style,
						mxConstants.STYLE_IMAGE_FLIPV, false);

				elem = createImageElement(x, y, w, h, img,
						PRESERVE_IMAGE_ASPECT, flipH, flipV, isEmbedded());
			}
		}
		else if (shape.equals(mxConstants.SHAPE_LINE))
		{
			String direction = mxUtils.getString(style,
					mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
			String d = null;

			if (direction.equals(mxConstants.DIRECTION_EAST)
					|| direction.equals(mxConstants.DIRECTION_WEST))
			{
				int mid = (y + h / 2);
				d = "M " + x + " " + mid + " L " + (x + w) + " " + mid;
			}
			else
			{
				int mid = (x + w / 2);
				d = "M " + mid + " " + y + " L " + mid + " " + (y + h);
			}

			elem = document.createElement("path");
			elem.setAttribute("d", d + " Z");
		}
		else if (shape.equals(mxConstants.SHAPE_ELLIPSE))
		{
			elem = document.createElement("ellipse");

			elem.setAttribute("cx", String.valueOf(x + w / 2));
			elem.setAttribute("cy", String.valueOf(y + h / 2));
			elem.setAttribute("rx", String.valueOf(w / 2));
			elem.setAttribute("ry", String.valueOf(h / 2));
		}
		else if (shape.equals(mxConstants.SHAPE_DOUBLE_ELLIPSE))
		{
			elem = document.createElement("g");
			background = document.createElement("ellipse");
			background.setAttribute("cx", String.valueOf(x + w / 2));
			background.setAttribute("cy", String.valueOf(y + h / 2));
			background.setAttribute("rx", String.valueOf(w / 2));
			background.setAttribute("ry", String.valueOf(h / 2));
			elem.appendChild(background);

			int inset = (int) ((3 + strokeWidth) * scale);

			Element foreground = document.createElement("ellipse");
			foreground.setAttribute("fill", "none");
			foreground.setAttribute("stroke", strokeColor);
			foreground
					.setAttribute("stroke-width", String.valueOf(strokeWidth));

			foreground.setAttribute("cx", String.valueOf(x + w / 2));
			foreground.setAttribute("cy", String.valueOf(y + h / 2));
			foreground.setAttribute("rx", String.valueOf(w / 2 - inset));
			foreground.setAttribute("ry", String.valueOf(h / 2 - inset));
			elem.appendChild(foreground);
		}
		else if (shape.equals(mxConstants.SHAPE_RHOMBUS))
		{
			elem = document.createElement("path");

			String d = "M " + (x + w / 2) + " " + y + " L " + (x + w) + " "
					+ (y + h / 2) + " L " + (x + w / 2) + " " + (y + h) + " L "
					+ x + " " + (y + h / 2);

			elem.setAttribute("d", d + " Z");
		}
		else if (shape.equals(mxConstants.SHAPE_TRIANGLE))
		{
			elem = document.createElement("path");
			String direction = mxUtils.getString(style,
					mxConstants.STYLE_DIRECTION, "");
			String d = null;

			if (direction.equals(mxConstants.DIRECTION_NORTH))
			{
				d = "M " + x + " " + (y + h) + " L " + (x + w / 2) + " " + y
						+ " L " + (x + w) + " " + (y + h);
			}
			else if (direction.equals(mxConstants.DIRECTION_SOUTH))
			{
				d = "M " + x + " " + y + " L " + (x + w / 2) + " " + (y + h)
						+ " L " + (x + w) + " " + y;
			}
			else if (direction.equals(mxConstants.DIRECTION_WEST))
			{
				d = "M " + (x + w) + " " + y + " L " + x + " " + (y + h / 2)
						+ " L " + (x + w) + " " + (y + h);
			}
			else
			// east
			{
				d = "M " + x + " " + y + " L " + (x + w) + " " + (y + h / 2)
						+ " L " + x + " " + (y + h);
			}

			elem.setAttribute("d", d + " Z");
		}
		else if (shape.equals(mxConstants.SHAPE_HEXAGON))
		{
			elem = document.createElement("path");
			String direction = mxUtils.getString(style,
					mxConstants.STYLE_DIRECTION, "");
			String d = null;

			if (direction.equals(mxConstants.DIRECTION_NORTH)
					|| direction.equals(mxConstants.DIRECTION_SOUTH))
			{
				d = "M " + (x + 0.5 * w) + " " + y + " L " + (x + w) + " "
						+ (y + 0.25 * h) + " L " + (x + w) + " "
						+ (y + 0.75 * h) + " L " + (x + 0.5 * w) + " "
						+ (y + h) + " L " + x + " " + (y + 0.75 * h) + " L "
						+ x + " " + (y + 0.25 * h);
			}
			else
			{
				d = "M " + (x + 0.25 * w) + " " + y + " L " + (x + 0.75 * w)
						+ " " + y + " L " + (x + w) + " " + (y + 0.5 * h)
						+ " L " + (x + 0.75 * w) + " " + (y + h) + " L "
						+ (x + 0.25 * w) + " " + (y + h) + " L " + x + " "
						+ (y + 0.5 * h);
			}

			elem.setAttribute("d", d + " Z");
		}
		else if (shape.equals(mxConstants.SHAPE_CLOUD))
		{
			elem = document.createElement("path");

			String d = "M " + (x + 0.25 * w) + " " + (y + 0.25 * h) + " C "
					+ (x + 0.05 * w) + " " + (y + 0.25 * h) + " " + x + " "
					+ (y + 0.5 * h) + " " + (x + 0.16 * w) + " "
					+ (y + 0.55 * h) + " C " + x + " " + (y + 0.66 * h) + " "
					+ (x + 0.18 * w) + " " + (y + 0.9 * h) + " "
					+ (x + 0.31 * w) + " " + (y + 0.8 * h) + " C "
					+ (x + 0.4 * w) + " " + (y + h) + " " + (x + 0.7 * w) + " "
					+ (y + h) + " " + (x + 0.8 * w) + " " + (y + 0.8 * h)
					+ " C " + (x + w) + " " + (y + 0.8 * h) + " " + (x + w)
					+ " " + (y + 0.6 * h) + " " + (x + 0.875 * w) + " "
					+ (y + 0.5 * h) + " C " + (x + w) + " " + (y + 0.3 * h)
					+ " " + (x + 0.8 * w) + " " + (y + 0.1 * h) + " "
					+ (x + 0.625 * w) + " " + (y + 0.2 * h) + " C "
					+ (x + 0.5 * w) + " " + (y + 0.05 * h) + " "
					+ (x + 0.3 * w) + " " + (y + 0.05 * h) + " "
					+ (x + 0.25 * w) + " " + (y + 0.25 * h);

			elem.setAttribute("d", d + " Z");
		}
		else if (shape.equals(mxConstants.SHAPE_ACTOR))
		{
			elem = document.createElement("path");
			double width3 = w / 3;

			String d = " M " + x + " " + (y + h) + " C " + x + " "
					+ (y + 3 * h / 5) + " " + x + " " + (y + 2 * h / 5) + " "
					+ (x + w / 2) + " " + (y + 2 * h / 5) + " C "
					+ (x + w / 2 - width3) + " " + (y + 2 * h / 5) + " "
					+ (x + w / 2 - width3) + " " + y + " " + (x + w / 2) + " "
					+ y + " C " + (x + w / 2 + width3) + " " + y + " "
					+ (x + w / 2 + width3) + " " + (y + 2 * h / 5) + " "
					+ (x + w / 2) + " " + (y + 2 * h / 5) + " C " + (x + w)
					+ " " + (y + 2 * h / 5) + " " + (x + w) + " "
					+ (y + 3 * h / 5) + " " + (x + w) + " " + (y + h);

			elem.setAttribute("d", d + " Z");
		}
		else if (shape.equals(mxConstants.SHAPE_CYLINDER))
		{
			elem = document.createElement("g");
			background = document.createElement("path");

			double dy = Math.min(40, Math.floor(h / 5));
			String d = " M " + x + " " + (y + dy) + " C " + x + " "
					+ (y - dy / 3) + " " + (x + w) + " " + (y - dy / 3) + " "
					+ (x + w) + " " + (y + dy) + " L " + (x + w) + " "
					+ (y + h - dy) + " C " + (x + w) + " " + (y + h + dy / 3)
					+ " " + x + " " + (y + h + dy / 3) + " " + x + " "
					+ (y + h - dy);
			background.setAttribute("d", d + " Z");
			elem.appendChild(background);

			Element foreground = document.createElement("path");
			d = "M " + x + " " + (y + dy) + " C " + x + " " + (y + 2 * dy)
					+ " " + (x + w) + " " + (y + 2 * dy) + " " + (x + w) + " "
					+ (y + dy);

			foreground.setAttribute("d", d);
			foreground.setAttribute("fill", "none");
			foreground.setAttribute("stroke", strokeColor);
			foreground
					.setAttribute("stroke-width", String.valueOf(strokeWidth));

			elem.appendChild(foreground);
		}
		else
		{
			background = document.createElement("rect");
			elem = background;

			elem.setAttribute("x", String.valueOf(x));
			elem.setAttribute("y", String.valueOf(y));
			elem.setAttribute("width", String.valueOf(w));
			elem.setAttribute("height", String.valueOf(h));

			if (mxUtils.isTrue(style, mxConstants.STYLE_ROUNDED, false))
			{
				String r = String.valueOf(Math.min(w
						* mxConstants.RECTANGLE_ROUNDING_FACTOR, h
						* mxConstants.RECTANGLE_ROUNDING_FACTOR));

				elem.setAttribute("rx", r);
				elem.setAttribute("ry", r);
			}

			// Paints the label image
			if (shape.equals(mxConstants.SHAPE_LABEL))
			{
				String img = getImageForStyle(style);

				if (img != null)
				{
					String imgAlign = mxUtils.getString(style,
							mxConstants.STYLE_IMAGE_ALIGN,
							mxConstants.ALIGN_LEFT);
					String imgValign = mxUtils.getString(style,
							mxConstants.STYLE_IMAGE_VERTICAL_ALIGN,
							mxConstants.ALIGN_MIDDLE);
					int imgWidth = (int) (mxUtils.getInt(style,
							mxConstants.STYLE_IMAGE_WIDTH,
							mxConstants.DEFAULT_IMAGESIZE) * scale);
					int imgHeight = (int) (mxUtils.getInt(style,
							mxConstants.STYLE_IMAGE_HEIGHT,
							mxConstants.DEFAULT_IMAGESIZE) * scale);
					int spacing = (int) (mxUtils.getInt(style,
							mxConstants.STYLE_SPACING, 2) * scale);

					mxRectangle imageBounds = new mxRectangle(x, y, w, h);

					if (imgAlign.equals(mxConstants.ALIGN_CENTER))
					{
						imageBounds.setX(imageBounds.getX()
								+ (imageBounds.getWidth() - imgWidth) / 2);
					}
					else if (imgAlign.equals(mxConstants.ALIGN_RIGHT))
					{
						imageBounds.setX(imageBounds.getX()
								+ imageBounds.getWidth() - imgWidth - spacing
								- 2);
					}
					else
					// LEFT
					{
						imageBounds.setX(imageBounds.getX() + spacing + 4);
					}

					if (imgValign.equals(mxConstants.ALIGN_TOP))
					{
						imageBounds.setY(imageBounds.getY() + spacing);
					}
					else if (imgValign.equals(mxConstants.ALIGN_BOTTOM))
					{
						imageBounds
								.setY(imageBounds.getY()
										+ imageBounds.getHeight() - imgHeight
										- spacing);
					}
					else
					// MIDDLE
					{
						imageBounds.setY(imageBounds.getY()
								+ (imageBounds.getHeight() - imgHeight) / 2);
					}

					imageBounds.setWidth(imgWidth);
					imageBounds.setHeight(imgHeight);

					elem = document.createElement("g");
					elem.appendChild(background);

					Element imageElement = createImageElement(
							imageBounds.getX(), imageBounds.getY(),
							imageBounds.getWidth(), imageBounds.getHeight(),
							img, false, false, false, isEmbedded());

					if (opacity != 100)
					{
						String value = String.valueOf(opacity / 100);
						imageElement.setAttribute("opacity", value);
					}

					elem.appendChild(imageElement);
				}

				// Paints the glass effect
				if (mxUtils.isTrue(style, mxConstants.STYLE_GLASS, false))
				{
					double size = 0.4;

					// TODO: Mask with rectangle or rounded rectangle of label
					// Creates glass overlay
					Element glassOverlay = document.createElement("path");

					// LATER: Not sure what the behaviour is for mutiple SVG elements in page.
					// Probably its possible that this points to an element in another SVG
					// node which when removed will result in an undefined background.
					glassOverlay.setAttribute("fill", "url(#"
							+ getGlassGradientElement().getAttribute("id")
							+ ")");

					String d = "m " + (x - strokeWidth) + ","
							+ (y - strokeWidth) + " L " + (x - strokeWidth)
							+ "," + (y + h * size) + " Q " + (x + w * 0.5)
							+ "," + (y + h * 0.7) + " " + (x + w + strokeWidth)
							+ "," + (y + h * size) + " L "
							+ (x + w + strokeWidth) + "," + (y - strokeWidth)
							+ " z";
					glassOverlay.setAttribute("stroke-width",
							String.valueOf(strokeWidth / 2));
					glassOverlay.setAttribute("d", d);
					elem.appendChild(glassOverlay);
				}
			}
		}

		double rotation = mxUtils.getDouble(style, mxConstants.STYLE_ROTATION);
		int cx = x + w / 2;
		int cy = y + h / 2;

		Element bg = background;

		if (bg == null)
		{
			bg = elem;
		}

		if (!bg.getNodeName().equalsIgnoreCase("use")
				&& !bg.getNodeName().equalsIgnoreCase("image"))
		{
			if (!fillColor.equalsIgnoreCase("none")
					&& !gradientColor.equalsIgnoreCase("none"))
			{
				String direction = mxUtils.getString(style,
						mxConstants.STYLE_GRADIENT_DIRECTION);
				Element gradient = getGradientElement(fillColor, gradientColor,
						direction);

				if (gradient != null)
				{
					bg.setAttribute("fill",
							"url(#" + gradient.getAttribute("id") + ")");
				}
			}
			else
			{
				bg.setAttribute("fill", fillColor);
			}

			bg.setAttribute("stroke", strokeColor);
			bg.setAttribute("stroke-width", String.valueOf(strokeWidth));

			// Adds the shadow element
			Element shadowElement = null;

			if (mxUtils.isTrue(style, mxConstants.STYLE_SHADOW, false)
					&& !fillColor.equals("none"))
			{
				shadowElement = (Element) bg.cloneNode(true);

				shadowElement.setAttribute("transform",
						mxConstants.SVG_SHADOWTRANSFORM);
				shadowElement.setAttribute("fill", mxConstants.W3C_SHADOWCOLOR);
				shadowElement.setAttribute("stroke",
						mxConstants.W3C_SHADOWCOLOR);
				shadowElement.setAttribute("stroke-width",
						String.valueOf(strokeWidth));

				if (rotation != 0)
				{
					shadowElement.setAttribute("transform", "rotate("
							+ rotation + "," + cx + "," + cy + ") "
							+ mxConstants.SVG_SHADOWTRANSFORM);
				}

				if (opacity != 100)
				{
					String value = String.valueOf(opacity / 100);
					shadowElement.setAttribute("fill-opacity", value);
					shadowElement.setAttribute("stroke-opacity", value);
				}

				appendSvgElement(shadowElement);
			}
		}

		if (rotation != 0)
		{
			elem.setAttribute("transform", elem.getAttribute("transform")
					+ " rotate(" + rotation + "," + cx + "," + cy + ")");

		}

		if (opacity != 100)
		{
			String value = String.valueOf(opacity / 100);
			elem.setAttribute("fill-opacity", value);
			elem.setAttribute("stroke-opacity", value);
		}

		if (mxUtils.isTrue(style, mxConstants.STYLE_DASHED))
		{
			String pattern = mxUtils.getString(style, mxConstants.STYLE_DASH_PATTERN, "3, 3");
			elem.setAttribute("stroke-dasharray", pattern);
		}

		appendSvgElement(elem);

		return elem;
	}

	/**
	 * Draws the given lines as segments between all points of the given list
	 * of mxPoints.
	 *
	 * @param pts List of points that define the line.
	 * @param style Style to be used for painting the line.
	 */
	public Element drawLine(List<mxPoint> pts, Map<String, Object> style)
	{
		Element group = document.createElement("g");
		Element path = document.createElement("path");

		boolean rounded = mxUtils.isTrue(style, mxConstants.STYLE_ROUNDED,
				false);
		String strokeColor = mxUtils.getString(style,
				mxConstants.STYLE_STROKECOLOR);
		float tmpStroke = (mxUtils.getFloat(style,
				mxConstants.STYLE_STROKEWIDTH, 1));
		float strokeWidth = (float) (tmpStroke * scale);

		if (strokeColor != null && strokeWidth > 0)
		{
			// Draws the start marker
			Object marker = style.get(mxConstants.STYLE_STARTARROW);

			mxPoint pt = pts.get(1);
			mxPoint p0 = pts.get(0);
			mxPoint offset = null;

			if (marker != null)
			{
				float size = (mxUtils.getFloat(style,
						mxConstants.STYLE_STARTSIZE,
						mxConstants.DEFAULT_MARKERSIZE));
				offset = drawMarker(group, marker, pt, p0, size, tmpStroke,
						strokeColor);
			}
			else
			{
				double dx = pt.getX() - p0.getX();
				double dy = pt.getY() - p0.getY();

				double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
				double nx = dx * strokeWidth / dist;
				double ny = dy * strokeWidth / dist;

				offset = new mxPoint(nx / 2, ny / 2);
			}

			// Applies offset to the point
			if (offset != null)
			{
				p0 = (mxPoint) p0.clone();
				p0.setX(p0.getX() + offset.getX());
				p0.setY(p0.getY() + offset.getY());

				offset = null;
			}

			// Draws the end marker
			marker = style.get(mxConstants.STYLE_ENDARROW);

			pt = pts.get(pts.size() - 2);
			mxPoint pe = pts.get(pts.size() - 1);

			if (marker != null)
			{
				float size = (mxUtils.getFloat(style,
						mxConstants.STYLE_ENDSIZE,
						mxConstants.DEFAULT_MARKERSIZE));
				offset = drawMarker(group, marker, pt, pe, size, tmpStroke,
						strokeColor);
			}
			else
			{
				double dx = pt.getX() - p0.getX();
				double dy = pt.getY() - p0.getY();

				double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
				double nx = dx * strokeWidth / dist;
				double ny = dy * strokeWidth / dist;

				offset = new mxPoint(nx / 2, ny / 2);
			}

			// Applies offset to the point
			if (offset != null)
			{
				pe = (mxPoint) pe.clone();
				pe.setX(pe.getX() + offset.getX());
				pe.setY(pe.getY() + offset.getY());

				offset = null;
			}

			// Draws the line segments
			double arcSize = mxConstants.LINE_ARCSIZE * scale;
			pt = p0;
			String d = "M " + pt.getX() + " " + pt.getY();

			for (int i = 1; i < pts.size() - 1; i++)
			{
				mxPoint tmp = pts.get(i);
				double dx = pt.getX() - tmp.getX();
				double dy = pt.getY() - tmp.getY();

				if ((rounded && i < pts.size() - 1) && (dx != 0 || dy != 0))
				{
					// Draws a line from the last point to the current
					// point with a spacing of size off the current point
					// into direction of the last point
					double dist = Math.sqrt(dx * dx + dy * dy);
					double nx1 = dx * Math.min(arcSize, dist / 2) / dist;
					double ny1 = dy * Math.min(arcSize, dist / 2) / dist;

					double x1 = tmp.getX() + nx1;
					double y1 = tmp.getY() + ny1;
					d += " L " + x1 + " " + y1;

					// Draws a curve from the last point to the current
					// point with a spacing of size off the current point
					// into direction of the next point
					mxPoint next = pts.get(i + 1);
					dx = next.getX() - tmp.getX();
					dy = next.getY() - tmp.getY();

					dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
					double nx2 = dx * Math.min(arcSize, dist / 2) / dist;
					double ny2 = dy * Math.min(arcSize, dist / 2) / dist;

					double x2 = tmp.getX() + nx2;
					double y2 = tmp.getY() + ny2;

					d += " Q " + tmp.getX() + " " + tmp.getY() + " " + x2 + " "
							+ y2;
					tmp = new mxPoint(x2, y2);
				}
				else
				{
					d += " L " + tmp.getX() + " " + tmp.getY();
				}

				pt = tmp;
			}

			d += " L " + pe.getX() + " " + pe.getY();

			path.setAttribute("d", d);
			path.setAttribute("stroke", strokeColor);
			path.setAttribute("fill", "none");
			path.setAttribute("stroke-width", String.valueOf(strokeWidth));

			if (mxUtils.isTrue(style, mxConstants.STYLE_DASHED))
			{
				String pattern = mxUtils.getString(style, mxConstants.STYLE_DASH_PATTERN, "3, 3");
				path.setAttribute("stroke-dasharray", pattern);
			}

			group.appendChild(path);
			appendSvgElement(group);
		}

		return group;
	}

	/**
	 * Draws the specified marker as a child path in the given parent.
	 */
	public mxPoint drawMarker(Element parent, Object type, mxPoint p0,
			mxPoint pe, float size, float strokeWidth, String color)
	{
		mxPoint offset = null;

		// Computes the norm and the inverse norm
		double dx = pe.getX() - p0.getX();
		double dy = pe.getY() - p0.getY();

		double dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
		double absSize = size * scale;
		double nx = dx * absSize / dist;
		double ny = dy * absSize / dist;

		pe = (mxPoint) pe.clone();
		pe.setX(pe.getX() - nx * strokeWidth / (2 * size));
		pe.setY(pe.getY() - ny * strokeWidth / (2 * size));

		nx *= 0.5 + strokeWidth / 2;
		ny *= 0.5 + strokeWidth / 2;

		Element path = document.createElement("path");
		path.setAttribute("stroke-width", String.valueOf(strokeWidth * scale));
		path.setAttribute("stroke", color);
		path.setAttribute("fill", color);

		String d = null;

		if (type.equals(mxConstants.ARROW_CLASSIC)
				|| type.equals(mxConstants.ARROW_BLOCK))
		{
			d = "M "
					+ pe.getX()
					+ " "
					+ pe.getY()
					+ " L "
					+ (pe.getX() - nx - ny / 2)
					+ " "
					+ (pe.getY() - ny + nx / 2)
					+ ((!type.equals(mxConstants.ARROW_CLASSIC)) ? "" : " L "
							+ (pe.getX() - nx * 3 / 4) + " "
							+ (pe.getY() - ny * 3 / 4)) + " L "
					+ (pe.getX() + ny / 2 - nx) + " "
					+ (pe.getY() - ny - nx / 2) + " z";
		}
		else if (type.equals(mxConstants.ARROW_OPEN))
		{
			nx *= 1.2;
			ny *= 1.2;

			d = "M " + (pe.getX() - nx - ny / 2) + " "
					+ (pe.getY() - ny + nx / 2) + " L " + (pe.getX() - nx / 6)
					+ " " + (pe.getY() - ny / 6) + " L "
					+ (pe.getX() + ny / 2 - nx) + " "
					+ (pe.getY() - ny - nx / 2) + " M " + pe.getX() + " "
					+ pe.getY();
			path.setAttribute("fill", "none");
		}
		else if (type.equals(mxConstants.ARROW_OVAL))
		{
			nx *= 1.2;
			ny *= 1.2;
			absSize *= 1.2;

			d = "M " + (pe.getX() - ny / 2) + " " + (pe.getY() + nx / 2)
					+ " a " + (absSize / 2) + " " + (absSize / 2) + " 0  1,1 "
					+ (nx / 8) + " " + (ny / 8) + " z";
		}
		else if (type.equals(mxConstants.ARROW_DIAMOND))
		{
			d = "M " + (pe.getX() + nx / 2) + " " + (pe.getY() + ny / 2)
					+ " L " + (pe.getX() - ny / 2) + " " + (pe.getY() + nx / 2)
					+ " L " + (pe.getX() - nx / 2) + " " + (pe.getY() - ny / 2)
					+ " L " + (pe.getX() + ny / 2) + " " + (pe.getY() - nx / 2)
					+ " z";
		}

		if (d != null)
		{
			path.setAttribute("d", d);
			parent.appendChild(path);
		}

		return offset;
	}

	/**
	 * Draws the specified text either using drawHtmlString or using drawString.
	 *
	 * @param text Text to be painted.
	 * @param x X-coordinate of the text.
	 * @param y Y-coordinate of the text.
	 * @param w Width of the text.
	 * @param h Height of the text.
	 * @param style Style to be used for painting the text.
	 */
	public Object drawText(String text, int x, int y, int w, int h,
			Map<String, Object> style)
	{
		Element elem = null;
		String fontColor = mxUtils.getString(style,
				mxConstants.STYLE_FONTCOLOR, "black");
		String fontFamily = mxUtils.getString(style,
				mxConstants.STYLE_FONTFAMILY, mxConstants.DEFAULT_FONTFAMILIES);
		int fontSize = (int) (mxUtils.getInt(style, mxConstants.STYLE_FONTSIZE,
				mxConstants.DEFAULT_FONTSIZE) * scale);

		if (text != null && text.length() > 0)
		{
			float strokeWidth = (float) (mxUtils.getFloat(style,
					mxConstants.STYLE_STROKEWIDTH, 1) * scale);

			// Applies the opacity
			float opacity = mxUtils.getFloat(style,
					mxConstants.STYLE_TEXT_OPACITY, 100);

			// Draws the label background and border
			String bg = mxUtils.getString(style,
					mxConstants.STYLE_LABEL_BACKGROUNDCOLOR);
			String border = mxUtils.getString(style,
					mxConstants.STYLE_LABEL_BORDERCOLOR);

			String transform = null;

			if (!mxUtils.isTrue(style, mxConstants.STYLE_HORIZONTAL, true))
			{
				double cx = x + w / 2;
				double cy = y + h / 2;
				transform = "rotate(270 " + cx + " " + cy + ")";
			}

			if (bg != null || border != null)
			{
				Element background = document.createElement("rect");

				background.setAttribute("x", String.valueOf(x));
				background.setAttribute("y", String.valueOf(y));
				background.setAttribute("width", String.valueOf(w));
				background.setAttribute("height", String.valueOf(h));

				if (bg != null)
				{
					background.setAttribute("fill", bg);
				}
				else
				{
					background.setAttribute("fill", "none");
				}

				if (border != null)
				{
					background.setAttribute("stroke", border);
				}
				else
				{
					background.setAttribute("stroke", "none");
				}

				background.setAttribute("stroke-width",
						String.valueOf(strokeWidth));

				if (opacity != 100)
				{
					String value = String.valueOf(opacity / 100);
					background.setAttribute("fill-opacity", value);
					background.setAttribute("stroke-opacity", value);
				}

				if (transform != null)
				{
					background.setAttribute("transform", transform);
				}

				appendSvgElement(background);
			}

			elem = document.createElement("text");

			int fontStyle = mxUtils.getInt(style, mxConstants.STYLE_FONTSTYLE);
			String weight = ((fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD) ? "bold"
					: "normal";
			elem.setAttribute("font-weight", weight);
			String uline = ((fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE) ? "underline"
					: "none";
			elem.setAttribute("font-decoration", uline);

			if ((fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC)
			{
				elem.setAttribute("font-style", "italic");
			}

			elem.setAttribute("font-size", String.valueOf(fontSize));
			elem.setAttribute("font-family", fontFamily);
			elem.setAttribute("fill", fontColor);

			if (opacity != 100)
			{
				String value = String.valueOf(opacity / 100);
				elem.setAttribute("fill-opacity", value);
				elem.setAttribute("stroke-opacity", value);
			}

			int swingFontStyle = ((fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD) ? Font.BOLD
					: Font.PLAIN;
			swingFontStyle += ((fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC) ? Font.ITALIC
					: Font.PLAIN;

			String[] lines = text.split("\n");
			y += fontSize
					+ (h - lines.length * (fontSize + mxConstants.LINESPACING))
					/ 2 - 2;

			String align = mxUtils.getString(style, mxConstants.STYLE_ALIGN,
					mxConstants.ALIGN_CENTER);
			String anchor = "start";

			if (align.equals(mxConstants.ALIGN_RIGHT))
			{
				anchor = "end";
				x += w - mxConstants.LABEL_INSET * scale;
			}
			else if (align.equals(mxConstants.ALIGN_CENTER))
			{
				anchor = "middle";
				x += w / 2;
			}
			else
			{
				x += mxConstants.LABEL_INSET * scale;
			}

			elem.setAttribute("text-anchor", anchor);

			for (int i = 0; i < lines.length; i++)
			{
				Element tspan = document.createElement("tspan");

				tspan.setAttribute("x", String.valueOf(x));
				tspan.setAttribute("y", String.valueOf(y));

				tspan.appendChild(document.createTextNode(lines[i]));
				elem.appendChild(tspan);

				y += fontSize + mxConstants.LINESPACING;
			}

			if (transform != null)
			{
				elem.setAttribute("transform", transform);
			}

			appendSvgElement(elem);
		}

		return elem;
	}

}


text:
require 'spec_helper'
require 'core_ext/module/prepend_to'

describe 'Module.prepend_to' do
  let(:klass) do
    Class.new do
      def called
        @called ||= []
      end

      def foo(*args)
        called << :original
      end
    end
  end

  let(:object) { klass.new }
  let(:method) { klass.instance_method(:foo) }

  def prepend!(arg = nil)
    klass.prepend_to :foo do |object, method, *args|
      object.called << arg
      method.call(*args)
    end
  end

  it 'calls the given method first and the original method second' do
    prepend!(:prepended)
    object.foo
    object.called.should == [:prepended, :original]
  end

  it 'can be called multiple times' do
    1.upto(3) { |n| prepend!(n) }
    object.foo
    object.called.should == [3, 2, 1, :original]
  end
end

redpajama_set_name: RedPajamaGithub


text:
all :
	ghc --make -Wall Mastermind.hs

clean :
	rm -f Mastermind tMastermind *.hi *.o report.html

test :
	ghc --make -Wall tMastermind.hs
	./tMastermind

prove :
# cpan App::Prove
	prove --exec make test

provehtml :
# cpan App::Prove::Plugin::HTML
	prove -P HTML=outfile:report.html --exec make test


text:
package edu.uiowa.slis.SPARQLTagLib;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.log4j.Logger;
import org.apache.taglibs.standard.tag.common.core.Util;

import edu.uiowa.slis.SPARQLTagLib.util.Endpoint;

@SuppressWarnings("serial")
public class SetEndpointTag extends TagSupport {
    static Logger logger = Logger.getLogger(SetEndpointTag.class);

    String sparqlURL = null;
    String user = null;
    String password = null;

    Endpoint endpoint = null;

    private int scope = PageContext.PAGE_SCOPE;
    private String var = null;

    public SetEndpointTag() {
	super();
	init();
    }

    private void init() {
	sparqlURL = null;
	user = null;
	password = null;

	scope = PageContext.PAGE_SCOPE;
	var = null;
    }

    public int doStartTag() throws JspException {
	logger.debug("setting var " + var + " to " + sparqlURL);
	endpoint = new Endpoint(sparqlURL);
	pageContext.setAttribute(var, endpoint, scope);
	return EVAL_BODY_INCLUDE;
    }

    public void release() {
	init();
    }

    public void setScope(String scope) {
	this.scope = Util.getScope(scope);
    }

    public void setVar(String var) {
	this.var = var;
    }

    public String getSparqlURL() {
	return sparqlURL;
    }

    public void setSparqlURL(String sparqlURL) {
	this.sparqlURL = sparqlURL;
    }

    public String getUser() {
	return user;
    }

    public void setUser(String user) {
	this.user = user;
    }

    public String getPassword() {
	return password;
    }

    public void setPassword(String password) {
	this.password = password;
    }

}


text:
service='low-battery'
systemctl stop "$service"
systemctl disable "$service"
rm /etc/$service.conf
rm -rf /usr/share/low-battery
rm /usr/local/bin/$service
rm /lib/systemd/system/$service.service


text:
/**
 * Module dependencies
 */

var stats = require('..');

var app = module.exports = stats();


text:
//------------------------------------------------------------------------------
// <gerado automaticamente>
//     Este código foi gerado por uma ferramenta.
//
//     As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se
//     o código for recriado
// </gerado automaticamente>
//------------------------------------------------------------------------------

namespace WebH2O {

    public partial class cadastro {

        /// <summary>
        /// Controle form1.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.HtmlControls.HtmlForm form1;

        /// <summary>
        /// Controle coluna1.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.HtmlControls.HtmlGenericControl coluna1;

        /// <summary>
        /// Controle boxID.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxID;

        /// <summary>
        /// Controle boxNome.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxNome;

        /// <summary>
        /// Controle boxCpf.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxCpf;

        /// <summary>
        /// Controle boxRg.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxRg;

        /// <summary>
        /// Controle btnPasso1.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Button btnPasso1;

        /// <summary>
        /// Controle panelErroUsuario.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Panel panelErroUsuario;

        /// <summary>
        /// Controle errousuario.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Label errousuario;

        /// <summary>
        /// Controle coluna2.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.HtmlControls.HtmlGenericControl coluna2;

        /// <summary>
        /// Controle boxLogradouro.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxLogradouro;

        /// <summary>
        /// Controle boxNumero.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxNumero;

        /// <summary>
        /// Controle boxComplemento.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxComplemento;

        /// <summary>
        /// Controle boxBairro.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxBairro;

        /// <summary>
        /// Controle boxCidade.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxCidade;

        /// <summary>
        /// Controle boxCep.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxCep;

        /// <summary>
        /// Controle Button1.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Button Button1;

        /// <summary>
        /// Controle panelErroEndereco.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Panel panelErroEndereco;

        /// <summary>
        /// Controle erroendereco.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Label erroendereco;

        /// <summary>
        /// Controle coluna3.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.HtmlControls.HtmlGenericControl coluna3;

        /// <summary>
        /// Controle boxEmail.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxEmail;

        /// <summary>
        /// Controle boxConfEmail.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxConfEmail;

        /// <summary>
        /// Controle boxSenha.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxSenha;

        /// <summary>
        /// Controle boxConfSenha.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.TextBox boxConfSenha;

        /// <summary>
        /// Controle Button2.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Button Button2;

        /// <summary>
        /// Controle panelErroInfo.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Panel panelErroInfo;

        /// <summary>
        /// Controle erroinfo.
        /// </summary>
        /// <remarks>
        /// Campo gerado automaticamente.
        /// Modificar a declaração do campo de movimento do arquivo de designer para o arquivo code-behind.
        /// </remarks>
        protected global::System.Web.UI.WebControls.Label erroinfo;
    }
}


text:
from contextlib import contextmanager
import multiprocessing
import logging

class MemoryCache(object):

    def __init__(self):
        self._lock = multiprocessing.Lock()
        self._manager = multiprocessing.Manager()
        self._cache = self._manager.dict()

    @contextmanager
    def lock(self, key):
        self._lock.acquire(timeout=60)
        try:
            yield
        finally:
            self._lock.release()

    def get(self, key):
        return self._cache.get(key.hash, None)

    def install(self, seedKey, seedEntry):
        logging.debug('Adding seed for key %(key)s to cache', dict(key=seedKey))
        self._cache[seedKey.hash] = seedEntry['code']

from strato.racktest.infra.seed import cacheregistry
cacheregistry.register('memory', MemoryCache.__init__)


text:
using UnityEngine;
//using UnityEngine.Assertions;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;

using SDD.Events;
using Colors.Events;

namespace Examples.Integration.Test {

  /// <summary>
  /// All integration tests are based on IntegrationTestBase
  /// </summary>
  public class IntegrationTestBase : EventHandler {

    /// <summary>
    /// Convenience getter for test delay
    /// </summary>
    public float DebugDelay { get { return IntegrationTestManager.Instance.debugDelay; }}

    protected override void OnDisable() {
      Debug.Log("IntegrationTestBase.OnDisable()");
      base.OnDisable();

      After();
      if (IntegrationTestManager.Instance != null) {
        IntegrationTestManager.Instance.AfterEach();
      }
    }

    /// <summary>
    /// Before runs before EACH test
    /// </summary>
    protected virtual void Before() {
      //Debug.Log("IntegrationTestBase.Before()");

      // override me
    }

    /// <summary>
    /// After runs after EACH test
    /// </summary>
    protected virtual void After() {
      //Debug.Log("IntegrationTestBase.After()");

      // override me
    }

    public override void SubscribeEvents() {
      // override me
    }

    public override void UnsubscribeEvents(){
      // override me
    }

    protected virtual IEnumerator Start() {
      // wait one frame for the GameManager
      yield return null;

      //
      // Init singletons here
      //

      IntegrationTestManager.Instance.BeforeEach();
      Before();

      // wait one frame for the Before() in case MonoBehaviours need to spin up
      yield return null;

      // NOTE: If Run needs to wait more than one frame to start, it should manage that on its own
      yield return StartCoroutine(Run());
    }

    /// <summary>
    /// Run contains the core logic of each test
    /// </summary>
    protected virtual IEnumerator Run() {
      // override me
      yield break;
    }

    /// <summary>
    /// Wait forever
    /// </summary>
    public static IEnumerator WaitForever() {
      while (true) {
        yield return null;
      }
    }
  }
}


text:
require File.expand_path('../../../test_helper', __FILE__)

class RoutingCustomFieldsTest < ActionController::IntegrationTest
  def test_custom_fields
    assert_routing(
        { :method => 'get', :path => "/custom_fields" },
        { :controller => 'custom_fields', :action => 'index' }
      )
    assert_routing(
        { :method => 'get', :path => "/custom_fields/new" },
        { :controller => 'custom_fields', :action => 'new' }
      )
    assert_routing(
        { :method => 'post', :path => "/custom_fields" },
        { :controller => 'custom_fields', :action => 'create' }
      )
    assert_routing(
        { :method => 'get', :path => "/custom_fields/2/edit" },
        { :controller => 'custom_fields', :action => 'edit', :id => '2' }
      )
    assert_routing(
        { :method => 'put', :path => "/custom_fields/2" },
        { :controller => 'custom_fields', :action => 'update', :id => '2' }
      )
    assert_routing(
        { :method => 'delete', :path => "/custom_fields/2" },
        { :controller => 'custom_fields', :action => 'destroy', :id => '2' }
      )
  end

  def test_custom_fields_api
    assert_routing(
        { :method => 'get', :path => "/custom_fields.xml" },
        { :controller => 'custom_fields', :action => 'index', :format => 'xml' }
      )
  end
end


text: require 'testing_gem_with_steve_spec'


text:
import { c } from 'ttag';

import { IMPORT_CALENDAR_FAQ_URL } from '@proton/shared/lib/calendar/constants';
import { getKnowledgeBaseUrl } from '@proton/shared/lib/helpers/url';

import { Href } from '../../../link';

const DefaultCalendarInstructions = () => {
    // translator: full sentence: "To import a calendar to Proton, you need the ICS file. Download this before you start the import process."
    const knowledgeBaseLink = (
        <Href url={getKnowledgeBaseUrl(IMPORT_CALENDAR_FAQ_URL)} key="knowledgeBaseLink">
            {c('Import instructions link').t`ICS file`}
        </Href>
    );
    // translator: full sentence: "To import a calendar to Proton, you need the ICS file. Download this before you start the import process."
    const defaultCalendarMessage = c('Import instructions')
        .jt`To import a calendar to Proton, you need the ${knowledgeBaseLink}. Download this before you start the import process.`;

    return
{defaultCalendarMessage}
;
};

export default DefaultCalendarInstructions;


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="Apache Forrest" name="Generator">
<meta name="Forrest-version" content="0.8">
<meta name="Forrest-skin-name" content="pelt">
<title>Capacity Scheduler Guide</title>
<link type="text/css" href="skin/basic.css" rel="stylesheet">
<link media="screen" type="text/css" href="skin/screen.css" rel="stylesheet">
<link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
<link type="text/css" href="skin/profile.css" rel="stylesheet">

<link rel="shortcut icon" href="images/favicon.ico">

Apache > Hadoop > Core

<form action="http://www.google.com/search" method="get" class="roundtopsmall">
<input value="archive.cloudera.com" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" size="25" name="q" id="query" type="text" value="Search the site with google">
                    <input name="Search" value="Search" type="submit">
</form>

Project

Wiki

Hadoop 0.20 Documentation

Getting Started

Overview

Single Node Setup

Cluster Setup

Guides

Authentication for Hadoop HTTP web-consoles

MapReduce

MapReduce Tutorial

Hadoop Streaming

Hadoop Commands

DistCp

Vaidya

Hadoop Archives

Gridmix

Capacity Scheduler

Fair Scheduler

Hod Scheduler

HDFS

HDFS Users

HDFS Architecture

Permissions

Quotas

Offline Image Viewer Guide

Synthetic Load Generator

C API libhdfs

Common

File System Shell

Service Level Authorization

Native Libraries

Miscellaneous

Secure Impersonation

API Docs

API Changes

Wiki

FAQ

Release Notes

Change Log

        PDF

Capacity Scheduler Guide

Purpose

Features

Picking a task to run

Installation

Configuration

Using the Capacity Scheduler

Setting up queues

Configuring properties for queues

Memory management

Job Initialization Parameters

Reviewing the configuration of the Capacity Scheduler

Purpose

This document describes the Capacity Scheduler, a pluggable
      MapReduce scheduler for Hadoop which provides a way to share
      large clusters.

Features

The Capacity Scheduler supports the following features:

          Support for multiple queues, where a job is submitted to a queue.

          Queues are allocated a fraction of the capacity of the grid in the
          sense that a certain capacity of resources will be at their
          disposal. All jobs submitted to a queue will have access to the
          capacity allocated to the queue.

          Free resources can be allocated to any queue beyond it's capacity.
          When there is demand for these resources from queues running below
          capacity at a future point in time, as tasks scheduled on these
          resources complete, they will be assigned to jobs on queues
          running below the capacity.

          Queues optionally support job priorities (disabled by default).

          Within a queue, jobs with higher priority will have access to the
          queue's resources before jobs with lower priority. However, once a
          job is running, it will not be preempted for a higher priority job,
          though new tasks from the higher priority job will be
          preferentially scheduled.

          In order to prevent one or more users from monopolizing its
          resources, each queue enforces a limit on the percentage of
          resources allocated to a user at any given time, if there is
          competition for them.

          Support for memory-intensive jobs, wherein a job can optionally
          specify higher memory-requirements than the default, and the tasks
          of the job will only be run on TaskTrackers that have enough memory
          to spare.

Picking a task to run

Note that many of these steps can be, and will be, enhanced over time
      to provide better algorithms.

Whenever a TaskTracker is free, the Capacity Scheduler picks
      a queue which has most free space (whose ratio of # of running slots to
      capacity is the lowest).

Once a queue is selected, the Scheduler picks a job in the queue. Jobs
      are sorted based on when they're submitted and their priorities (if the
      queue supports priorities). Jobs are considered in order, and a job is
      selected if its user is within the user-quota for the queue, i.e., the
      user is not already using queue resources above his/her limit. The
      Scheduler also makes sure that there is enough free memory in the
      TaskTracker to tun the job's task, in case the job has special memory
      requirements.

Once a job is selected, the Scheduler picks a task to run. This logic
      to pick a task remains unchanged from earlier versions.

Installation

The Capacity Scheduler is available as a JAR file in the Hadoop
        tarball under the contrib/capacity-scheduler directory. The name of
        the JAR file would be on the lines of hadoop-capacity-scheduler-*.jar.

You can also build the Scheduler from source by executing
        ant package, in which case it would be available under
        build/contrib/capacity-scheduler.

To run the Capacity Scheduler in your Hadoop installation, you need
        to put it on the CLASSPATH. The easiest way is to copy the
        hadoop-capacity-scheduler-*.jar from
        to HADOOP_HOME/lib. Alternatively, you can modify
        HADOOP_CLASSPATH to include this jar, in
        conf/hadoop-env.sh.

Configuration

Using the Capacity Scheduler

          To make the Hadoop framework use the Capacity Scheduler, set up
          the following property in the site configuration:

Property
              Value

mapred.jobtracker.taskScheduler
              org.apache.hadoop.mapred.CapacityTaskScheduler

Setting up queues

          You can define multiple queues to which users can submit jobs with
          the Capacity Scheduler. To define multiple queues, you should edit
          the site configuration for Hadoop and modify the
          mapred.queue.names property.

          You can also configure ACLs for controlling which users or groups
          have access to the queues.

          For more details, refer to
          Cluster
          Setup documentation.

Configuring properties for queues

The Capacity Scheduler can be configured with several properties
        for each queue that control the behavior of the Scheduler. This
        configuration is in the conf/capacity-scheduler.xml. By
        default, the configuration is set up for one queue, named
        default.

To specify a property for a queue that is defined in the site
        configuration, you should use the property name as
        mapred.capacity-scheduler.queue.<queue-name>.<property-name>.

For example, to define the property capacity
        for queue named research, you should specify the property
        name as
        mapred.capacity-scheduler.queue.research.capacity.

The properties defined for queues and their descriptions are
        listed in the table below:

Name	Description

mapred.capacity-scheduler.queue.<queue-name>.capacity
          	Percentage of the number of slots in the cluster that are made
            to be available for jobs in this queue. The sum of capacities
            for all queues should be less than or equal 100.

mapred.capacity-scheduler.queue.<queue-name>.supports-priority
          	If true, priorities of jobs will be taken into account in scheduling
          	decisions.

mapred.capacity-scheduler.queue.<queue-name>.minimum-user-limit-percent
          	Each queue enforces a limit on the percentage of resources
          	allocated to a user at any given time, if there is competition
          	for them. This user limit can vary between a minimum and maximum
          	value. The former depends on the number of users who have submitted
          	jobs, and the latter is set to this property value. For example,
          	suppose the value of this property is 25. If two users have
          	submitted jobs to a queue, no single user can use more than 50%
          	of the queue resources. If a third user submits a job, no single
          	user can use more than 33% of the queue resources. With 4 or more
          	users, no user can use more than 25% of the queue's resources. A
          	value of 100 implies no user limits are imposed.

mapred.capacity-scheduler.queue.<queue-name>.maximum-capacity

                  maximum-capacity defines a limit beyond which a queue cannot
                  use the capacity of the cluster.This provides a means to limit
                  how much excess capacity a queue can use. By default, there
                  is no limit.
                  The maximum-capacity of a queue can only be greater than or
                  equal to its minimum capacity.
                  Default value of -1 implies a queue can use complete capacity
                  of the cluster.

                  This property could be to curtail certain jobs which are long
                  running in nature from occupying more than a certain
                  percentage of the cluster, which in the absence of
                  pre-emption, could lead to capacity guarantees of other queues
                  being affected.

                  One important thing to note is that maximum-capacity is a
                  percentage , so based on the cluster's capacity
                  it would change. So if large no of nodes or racks get added
                  to the cluster , maximum Capacity in
                  absolute terms would increase accordingly.

Memory management

The Capacity Scheduler supports scheduling of tasks on a
        TaskTracker(TT) based on a job's memory requirements
        and the availability of RAM and Virtual Memory (VMEM) on the TT node.
        See the
        MapReduce Tutorial for details on how the TT monitors
        memory usage.

Currently the memory based scheduling is only supported
        in Linux platform.

Memory-based scheduling works as follows:

The absence of any one or more of three config parameters
          or -1 being set as value of any of the parameters,
          mapred.tasktracker.vmem.reserved,
          mapred.task.default.maxvmem, or
          mapred.task.limit.maxvmem, disables memory-based
          scheduling, just as it disables memory monitoring for a TT. These
          config parameters are described in the
          MapReduce
          Tutorial. The value of
          mapred.tasktracker.vmem.reserved is
          obtained from the TT via its heartbeat.

If all the three mandatory parameters are set, the Scheduler
          enables VMEM-based scheduling. First, the Scheduler computes the free
          VMEM on the TT. This is the difference between the available VMEM on the
          TT (the node's total VMEM minus the offset, both of which are sent by
          the TT on each heartbeat)and the sum of VMs already allocated to
          running tasks (i.e., sum of the VMEM task-limits). Next, the Scheduler
          looks at the VMEM requirements for the job that's first in line to
          run. If the job's VMEM requirements are less than the available VMEM on
          the node, the job's task can be scheduled. If not, the Scheduler
          ensures that the TT does not get a task to run (provided the job
          has tasks to run). This way, the Scheduler ensures that jobs with
          high memory requirements are not starved, as eventually, the TT
          will have enough VMEM available. If the high-mem job does not have
          any task to run, the Scheduler moves on to the next job.

In addition to VMEM, the Capacity Scheduler can also consider
          RAM on the TT node. RAM is considered the same way as VMEM. TTs report
          the total RAM available on their node, and an offset. If both are
          set, the Scheduler computes the available RAM on the node. Next,
          the Scheduler figures out the RAM requirements of the job, if any.
          As with VMEM, users can optionally specify a RAM limit for their job
          (mapred.task.maxpmem, described in the MapReduce
          Tutorial). The Scheduler also maintains a limit for this value
          (mapred.capacity-scheduler.task.default-pmem-percentage-in-vmem,
          described below). All these three values must be set for the
          Scheduler to schedule tasks based on RAM constraints.

The Scheduler ensures that jobs cannot ask for RAM or VMEM higher
          than configured limits. If this happens, the job is failed when it
          is submitted.

As described above, the additional scheduler-based config
        parameters are as follows:

Name	Description

mapred.capacity-scheduler.task.default-pmem-percentage-in-vmem
          	A percentage of the default VMEM limit for jobs
          	(mapred.task.default.maxvmem). This is the default
          	RAM task-limit associated with a task. Unless overridden by a
          	job's setting, this number defines the RAM task-limit.

mapred.capacity-scheduler.task.limit.maxpmem
          Configuration which provides an upper limit to maximum physical
           memory which can be specified by a job. If a job requires more
           physical memory than what is specified in this limit then the same
           is rejected.

Job Initialization Parameters

Capacity scheduler lazily initializes the jobs before they are
        scheduled, for reducing the memory footprint on jobtracker.
        Following are the parameters, by which you can control the laziness
        of the job initialization. The following parameters can be
        configured in capacity-scheduler.xml

Name	Description

              mapred.capacity-scheduler.queue.<queue-name>.maximum-initialized-jobs-per-user

              Maximum number of jobs which are allowed to be pre-initialized for
              a particular user in the queue. Once a job is scheduled, i.e.
              it starts running, then that job is not considered
              while scheduler computes the maximum job a user is allowed to
              initialize.

              mapred.capacity-scheduler.init-poll-interval

              Amount of time in miliseconds which is used to poll the scheduler
              job queue to look for jobs to be initialized.

              mapred.capacity-scheduler.init-worker-threads

              Number of worker threads which would be used by Initialization
              poller to initialize jobs in a set of queue. If number mentioned
              in property is equal to number of job queues then a thread is
              assigned jobs from one queue. If the number configured is lesser than
              number of queues, then a thread can get jobs from more than one queue
              which it initializes in a round robin fashion. If the number configured
              is greater than number of queues, then number of threads spawned
              would be equal to number of job queues.

Reviewing the configuration of the Capacity Scheduler

          Once the installation and configuration is completed, you can review
          it after starting the MapReduce cluster from the admin UI.

Start the MapReduce cluster as usual.

Open the JobTracker web UI.

The queues you have configured should be listed under the Scheduling
              Information section of the page.

The properties for the queues should be visible in the Scheduling
              Information column against each queue.

        Copyright ©
         2008 The Apache Software Foundation.


text:
package org.springframework.jmx.access;

import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.BindException;
import java.util.HashMap;
import java.util.Map;

import javax.management.Descriptor;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

import org.springframework.jmx.AbstractMBeanServerTests;
import org.springframework.jmx.IJmxTestBean;
import org.springframework.jmx.JmxException;
import org.springframework.jmx.JmxTestBean;
import org.springframework.jmx.export.MBeanExporter;
import org.springframework.jmx.export.assembler.AbstractReflectiveMBeanInfoAssembler;

/**
 * @author Rob Harrop
 * @author Juergen Hoeller
 */
public class MBeanClientInterceptorTests extends AbstractMBeanServerTests {

	protected static final String OBJECT_NAME = "spring:test=proxy";

	protected JmxTestBean target;

	protected boolean runTests = true;

	public void onSetUp() throws Exception {
		target = new JmxTestBean();
		target.setAge(100);
		target.setName("Rob Harrop");

		MBeanExporter adapter = new MBeanExporter();
		Map beans = new HashMap();
		beans.put(OBJECT_NAME, target);
		adapter.setServer(getServer());
		adapter.setBeans(beans);
		adapter.setAssembler(new ProxyTestAssembler());
		adapter.afterPropertiesSet();
	}

	protected MBeanServerConnection getServerConnection() throws Exception {
		return getServer();
	}

	protected IJmxTestBean getProxy() throws Exception {
		MBeanProxyFactoryBean factory = new MBeanProxyFactoryBean();
		factory.setServer(getServerConnection());
		factory.setProxyInterface(IJmxTestBean.class);
		factory.setObjectName(OBJECT_NAME);
		factory.afterPropertiesSet();
		return (IJmxTestBean) factory.getObject();
	}

	public void testProxyClassIsDifferent() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy = getProxy();
		assertTrue("The proxy class should be different than the base class",
				(proxy.getClass() != IJmxTestBean.class));
	}

	public void testDifferentProxiesSameClass() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy1 = getProxy();
		IJmxTestBean proxy2 = getProxy();

		assertNotSame("The proxies should NOT be the same", proxy1, proxy2);
		assertSame("The proxy classes should be the same", proxy1.getClass(), proxy2.getClass());
	}

	public void testGetAttributeValue() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy1 = getProxy();
		int age = proxy1.getAge();
		assertEquals("The age should be 100", 100, age);
	}

	public void testSetAttributeValue() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy = getProxy();
		proxy.setName("Rob Harrop");
		assertEquals("The name of the bean should have been updated", "Rob Harrop", target.getName());
	}

	public void testSetAttributeValueWithRuntimeException() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy = getProxy();
		try {
			proxy.setName("Juergen");
			fail("Should have thrown IllegalArgumentException");
		}
		catch (IllegalArgumentException ex) {
			// expected
		}
	}

	public void testSetAttributeValueWithCheckedException() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy = getProxy();
		try {
			proxy.setName("Juergen Class");
			fail("Should have thrown ClassNotFoundException");
		}
		catch (ClassNotFoundException ex) {
			// expected
		}
	}

	public void testSetAttributeValueWithIOException() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy = getProxy();
		try {
			proxy.setName("Juergen IO");
			fail("Should have thrown IOException");
		}
		catch (IOException ex) {
			// expected
		}
	}

	public void testSetReadOnlyAttribute() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy = getProxy();
		try {
			proxy.setAge(900);
			fail("Should not be able to write to a read only attribute");
		}
		catch (InvalidInvocationException ex) {
			// success
		}
	}

	public void testInvokeNoArgs() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy = getProxy();
		long result = proxy.myOperation();
		assertEquals("The operation should return 1", 1, result);
	}

	public void testInvokeArgs() throws Exception {
		if (!runTests) return;
		IJmxTestBean proxy = getProxy();
		int result = proxy.add(1, 2);
		assertEquals("The operation should return 3", 3, result);
	}

	public void testInvokeUnexposedMethodWithException() throws Exception {
		if (!runTests) return;
		IJmxTestBean bean = getProxy();
		try {
			bean.dontExposeMe();
			fail("Method dontExposeMe should throw an exception");
		}
		catch (InvalidInvocationException desired) {
			// success
		}
	}

	public void testLazyConnectionToRemote() throws Exception {
		if (!runTests) return;

		JMXServiceURL url = new JMXServiceURL("service:jmx:jmxmp://localhost:9876");
		JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, getServer());

		MBeanProxyFactoryBean factory = new MBeanProxyFactoryBean();
		factory.setServiceUrl(url.toString());
		factory.setProxyInterface(IJmxTestBean.class);
		factory.setObjectName(OBJECT_NAME);
		factory.setConnectOnStartup(false);
		factory.setRefreshOnConnectFailure(true);
		// should skip connection to the server
		factory.afterPropertiesSet();
		IJmxTestBean bean = (IJmxTestBean) factory.getObject();

		// now start the connector
		try {
			connector.start();
		}
		catch (BindException ex) {
			// couldn't bind to local port 9876 - let's skip the remainder of this test
			System.out.println(
					"Skipping JMX LazyConnectionToRemote test because binding to local port 9876 failed: " +
					ex.getMessage());
			return;
		}

		// should now be able to access data via the lazy proxy
		try {
			assertEquals("Rob Harrop", bean.getName());
			assertEquals(100, bean.getAge());
		}
		finally {
			connector.stop();
		}

		try {
			bean.getName();
		}
		catch (JmxException ex) {
			// expected
		}

		connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, getServer());
		connector.start();

		// should now be able to access data via the lazy proxy
		try {
			assertEquals("Rob Harrop", bean.getName());
			assertEquals(100, bean.getAge());
		}
		finally {
			connector.stop();
		}
	}

	// Commented out because of a side effect with the the started platform MBeanServer.
	/*
	public void testMXBeanAttributeAccess() throws Exception {
		if (org.springframework.core.JdkVersion.getMajorJavaVersion() < org.springframework.core.JdkVersion.JAVA_15) {
			return;
		}

		MBeanClientInterceptor interceptor = new MBeanClientInterceptor();
		interceptor.setServer(java.lang.management.ManagementFactory.getPlatformMBeanServer());
		interceptor.setObjectName("java.lang:type=Memory");
		interceptor.setManagementInterface(java.lang.management.MemoryMXBean.class);
		java.lang.management.MemoryMXBean proxy =
			(java.lang.management.MemoryMXBean) org.springframework.aop.framework.ProxyFactory.getProxy(java.lang.management.MemoryMXBean.class, interceptor);
		assertTrue(proxy.getHeapMemoryUsage().getMax() > 0);
	}

	public void testMXBeanOperationAccess() throws Exception {
		if (org.springframework.core.JdkVersion.getMajorJavaVersion() < org.springframework.core.JdkVersion.JAVA_15) {
			return;
		}

		MBeanClientInterceptor interceptor = new MBeanClientInterceptor();
		interceptor.setServer(java.lang.management.ManagementFactory.getPlatformMBeanServer());
		interceptor.setObjectName("java.lang:type=Threading");
		java.lang.management.ThreadMXBean proxy =
			(java.lang.management.ThreadMXBean) org.springframework.aop.framework.ProxyFactory.getProxy(java.lang.management.ThreadMXBean.class, interceptor);
		assertTrue(proxy.getThreadInfo(Thread.currentThread().getId()).getStackTrace() != null);
	}

	// This test passes under Windows with JDK 1.6.0_18
	// It fails on Mac OS X with JDK 1.6.0_17 (most recent as of Feb 24, 2010)
	// with a "java.lang.InternalError: Unsupported VMGlobal Type 0" exception
	public void testMXBeanAttributeListAccess() throws Exception {
		MBeanClientInterceptor interceptor = new MBeanClientInterceptor();
		interceptor.setServer(java.lang.management.ManagementFactory.getPlatformMBeanServer());
		interceptor.setObjectName("com.sun.management:type=HotSpotDiagnostic");
		com.sun.management.HotSpotDiagnosticMXBean proxy =
			(com.sun.management.HotSpotDiagnosticMXBean) org.springframework.aop.framework.ProxyFactory.getProxy(com.sun.management.HotSpotDiagnosticMXBean.class, interceptor);
		assertFalse(proxy.getDiagnosticOptions().isEmpty());
	}
	*/

	private static class ProxyTestAssembler extends AbstractReflectiveMBeanInfoAssembler {

		protected boolean includeReadAttribute(Method method, String beanKey) {
			return true;
		}

		protected boolean includeWriteAttribute(Method method, String beanKey) {
			if ("setAge".equals(method.getName())) {
				return false;
			}
			return true;
		}

		protected boolean includeOperation(Method method, String beanKey) {
			if ("dontExposeMe".equals(method.getName())) {
				return false;
			}
			return true;
		}

		protected String getOperationDescription(Method method) {
			return method.getName();
		}

		protected String getAttributeDescription(PropertyDescriptor propertyDescriptor) {
			return propertyDescriptor.getDisplayName();
		}

		protected void populateAttributeDescriptor(Descriptor descriptor, Method getter, Method setter) {

		}

		protected void populateOperationDescriptor(Descriptor descriptor, Method method) {

		}

		protected String getDescription(String beanKey, Class beanClass) {
			return "";
		}

		protected void populateMBeanDescriptor(Descriptor mbeanDescriptor, String beanKey, Class beanClass) {

		}
	}

}


text:
There exists a pre-built binary for Linux which does not require Java,
and starts up in <50ms.

## 1. Go to the latest release for zprint
You can find the latest release [here](https://github.com/kkinnear/zprint/releases/latest).
## 2. Download zprintl from the above directory
The Linux pre-built binary is named `zprintl-0.x.y`, where `x.y` varies.
Click on this to download it.
## 3. Name zprint whatever you want
The downloaded version of zprintl always has the version in the name.
You may wish to name it something different so that any scripts that
you have will use the new version without requiring a change.  We
will assume that you have renamed it `zprint`.
```
mv zprintl-1.2.4 zprint
```

Note that you can always find the version of zprintl (no matter what
you called it), by giving it the -v switch:
```
./zprint -v
zprint-1.2.4
```

## 3. Put zprint into a directory in your path
To be able to run zprint it needs to be in a directory that appears in
your path.

## 4. Test it with `--explain-all`

```
zprint --explain-all
{:agent {:object? false},
 :array {:hex? false, :indent 1, :object? false, :wrap? true},
 :atom {:object? false},
 :binding {:flow? false,
           :force-nl? false,
           :hang-diff 1,
           :hang-expand 2.0,
           :hang? true,
           :indent 2,
           :justify? false,
           :nl-separator? false},
[...]
```
The `--explain-all` switch will output the configuration zprint will use when
run. For any values that are not the default, this will include where that
value came from (for instance, if you set something in your `~/.zprintrc`,
that information will appear in the `--explain-all` output).
If you run `zprint --explain-all`, it should output a very large map showing
all of the configuration options and their current values.  Toward the
end, it will include a key `:version` which should be the version that
you just downloaded.

If you use the `-e` switch, you will see just the configuration options that
are different from the defaults, if any:

## 5. Try it
The zprint program you have installed will accept Clojure source on stdin
and produce formatted Clojure source on stdout.  It will also
accept an options map on the command line.  Note the need for single quotes
around any options map value that you specify.
```
zprint '{:width 90}' < myfile.clj
```
This will output a formatted version of `myfile.clj` to the controlling
terminal, fit into 90 (instead of the default 80) columns of output.