/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.core.internal.resources; import java.io.UnsupportedEncodingException; import java.util.Iterator; import java.util.Map; import org.eclipse.core.internal.utils.*; import org.eclipse.core.runtime.Assert; import org.eclipse.osgi.util.NLS; public class MarkerInfo implements IMarkerSetElement, Cloneable, IStringPoolParticipant { // well known Integer values protected static final Integer INTEGER_ONE= new Integer(1); protected static final Integer INTEGER_TWO= new Integer(2); protected static final Integer INTEGER_ZERO= new Integer(0); // protected static final long UNDEFINED_ID= -1; /** The store of attributes for this marker. */ protected Map attributes= null; /** The creation time for this marker. */ protected long creationTime= 0; /** Marker identifier. */ protected long id= UNDEFINED_ID; /** The type of this marker. */ protected String type= null; /** * Returns whether the given object is a valid attribute value. Returns either the attribute or * an equal canonical substitute. */ protected static Object checkValidAttribute(Object value) { if (value == null) return null; if (value instanceof String) { //we cannot write attributes whose UTF encoding exceeds 65535 bytes. String valueString= (String)value; //optimized test based on maximum 3 bytes per character if (valueString.length() < 21000) return value; byte[] bytes; try { bytes= valueString.getBytes(("UTF-8"));//$NON-NLS-1$ } catch (UnsupportedEncodingException uee) { //cannot validate further return value; } if (bytes.length > 65535) { String msg= "Marker property value is too long: " + valueString.substring(0, 10000); //$NON-NLS-1$ Assert.isTrue(false, msg); } return value; } if (value instanceof Boolean) { //return canonical boolean return ((Boolean)value).booleanValue() ? Boolean.TRUE : Boolean.FALSE; } if (value instanceof Integer) { //replace common integers with canonical values switch (((Integer)value).intValue()) { case 0: return INTEGER_ZERO; case 1: return INTEGER_ONE; case 2: return INTEGER_TWO; } return value; } //if we got here, it's an invalid attribute value type throw new IllegalArgumentException(NLS.bind(Messages.resources_wrongMarkerAttributeValueType, value.getClass().getName())); } public MarkerInfo() { super(); } /** * See Object#clone. */ public Object clone() { try { MarkerInfo copy= (MarkerInfo)super.clone(); //copy the attribute table contents copy.attributes= getAttributes(true); return copy; } catch (CloneNotSupportedException e) { //cannot happen because this class implements Cloneable return null; } } public Object getAttribute(String attributeName) { return attributes == null ? null : attributes.get(attributeName); } public Map getAttributes() { return getAttributes(true); } public Map getAttributes(boolean makeCopy) { if (attributes == null) return null; return makeCopy ? new MarkerAttributeMap(attributes) : attributes; } public Object[] getAttributes(String[] attributeNames) { Object[] result= new Object[attributeNames.length]; for (int i= 0; i < attributeNames.length; i++) result[i]= getAttribute(attributeNames[i]); return result; } public long getCreationTime() { return creationTime; } public long getId() { return id; } public String getType() { return type; } public void internalSetAttributes(Map map) { //the cast effectively acts as an assertion to make sure //the right kind of map is being used attributes= map; } public void setAttribute(String attributeName, Object value, boolean validate) { if (validate) value= checkValidAttribute(value); if (attributes == null) { if (value == null) return; attributes= new MarkerAttributeMap(); attributes.put(attributeName, value); } else { if (value == null) { attributes.remove(attributeName); if (attributes.isEmpty()) attributes= null; } else { attributes.put(attributeName, value); } } } public void setAttributes(Map map, boolean validate) { if (map == null) attributes= null; else { attributes= new MarkerAttributeMap(map.size()); for (Iterator i= map.keySet().iterator(); i.hasNext();) { Object key= i.next(); Assert.isTrue(key instanceof String); Object value= map.get(key); setAttribute((String)key, value, validate); } } } public void setAttributes(String[] attributeNames, Object[] values, boolean validate) { Assert.isTrue(attributeNames.length == values.length); for (int i= 0; i < attributeNames.length; i++) setAttribute(attributeNames[i], values[i], validate); } public void setCreationTime(long value) { creationTime= value; } public void setId(long value) { id= value; } public void setType(String value) { type= value; } /* (non-Javadoc * Method declared on IStringPoolParticipant */ public void shareStrings(StringPool set) { type= set.add(type); Map map= attributes; if (map instanceof IStringPoolParticipant) ((IStringPoolParticipant)map).shareStrings(set); } }