/** * Copyright 2009 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.safehaus.penrose.schema; import java.io.PrintWriter; import java.io.Serializable; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; public class ObjectClass implements Serializable, Cloneable, Comparable { public final static long serialVersionUID = 1L; public final static String ABSTRACT = "ABSTRACT"; public final static String STRUCTURAL = "STRUCTURAL"; public final static String AUXILIARY = "AUXILIARY"; /** * Identifier. */ public String oid; /** * Name. */ public Collection<String> names = new ArrayList<String>(); /** * Description. */ public String description; /** * Obsolete. */ public boolean obsolete; /** * Super class. */ public Collection<String> superClasses = new ArrayList<String>(); /** * Type (ABSTRACT, STRUCTURAL, AUXILIARY). Default: STRUCTURAL. */ public String type = STRUCTURAL; /** * Required attribute types. Each element is of type String. */ public Collection<String> requiredAttributes = new ArrayList<String>(); public Collection<String> normalizedRequiredAttributes = new HashSet<String>(); /** * Optional attribute types. Each element is of type String. */ public Collection<String> optionalAttributes = new ArrayList<String>(); public Collection<String> normalizedOptionalAttributes = new HashSet<String>(); public ObjectClass() { } public ObjectClass(String name, String superClass, String description) { this.names.add(name); this.superClasses.add(superClass); this.description = description; } public ObjectClass(Collection<String> names, Collection<String> superClasses, String description) { this.names.addAll(names); this.superClasses.addAll(superClasses); this.description = description; } public String getName() { if (names != null && names.size() >= 1) return names.iterator().next(); return null; } public void setName(String name) { names.clear(); names.add(name); } public void addName(String name) { names.add(name); } public Collection<String> getNames() { return names; } public void setNames(Collection<String> names) { if (this.names == names) return; this.names.clear(); this.names.addAll(names); } public void removeNames() { names.clear(); } public void addSuperClass(String superClass) { superClasses.add(superClass); } public Collection<String> getSuperClasses() { return superClasses; } public void setSuperClasses(Collection<String> superClasses) { if (this.superClasses == superClasses) return; this.superClasses.clear(); this.superClasses.addAll(superClasses); } public void removeSuperClasses() { superClasses.clear(); } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Collection<String> getRequiredAttributes() { return requiredAttributes; } public void addRequiredAttribute(String requiredAttribute) { requiredAttributes.add(requiredAttribute); normalizedRequiredAttributes.add(requiredAttribute.toLowerCase()); } public void addRequiredAttributes(Collection<String> requiredAttributes) { if (requiredAttributes == null) return; for (String requiredAttribute : requiredAttributes) { addRequiredAttribute(requiredAttribute); } } public void setRequiredAttributes(Collection<String> requiredAttributes) { if (this.requiredAttributes == requiredAttributes) return; removeRequiredAttributes(); addRequiredAttributes(requiredAttributes); } public void removeRequiredAttribute(String requiredAttribute) { requiredAttributes.remove(requiredAttribute); normalizedRequiredAttributes.remove(requiredAttribute.toLowerCase()); } public void removeRequiredAttributes() { requiredAttributes.clear(); normalizedRequiredAttributes.clear(); } public Collection<String> getOptionalAttributes() { return optionalAttributes; } public void addOptionalAttribute(String optionalAttribute) { optionalAttributes.add(optionalAttribute); normalizedOptionalAttributes.add(optionalAttribute.toLowerCase()); } public void addOptionalAttributes(Collection<String> optionalAttributes) { if (optionalAttributes == null) return; for (String optionalAttribute : optionalAttributes) { addOptionalAttribute(optionalAttribute); } } public void setOptionalAttributes(Collection<String> optionalAttributes) { if (this.optionalAttributes == optionalAttributes) return; removeOptionalAttributes(); addOptionalAttributes(optionalAttributes); } public void removeOptionalAttribute(String optionalAttribute) { optionalAttributes.remove(optionalAttribute); normalizedOptionalAttributes.remove(optionalAttribute.toLowerCase()); } public void removeOptionalAttributes() { optionalAttributes.clear(); normalizedOptionalAttributes.clear(); } public boolean isObsolete() { return obsolete; } /** * @param obsolete The obsolete to set. */ public void setObsolete(boolean obsolete) { this.obsolete = obsolete; } /** * @return Returns the oid. */ public String getOid() { return oid; } /** * @param oid The oid to set. */ public void setOid(String oid) { this.oid = oid; } /** * @return Returns the type. */ public String getType() { return type; } /** * @param type The type to set. */ public void setType(String type) { this.type = type; } public boolean containsRequiredAttribute(String name) { return normalizedRequiredAttributes.contains(name.toLowerCase()); } public boolean containsOptionalAttribute(String name) { return normalizedOptionalAttributes.contains(name.toLowerCase()); } public int hashCode() { return oid == null ? 0 : oid.hashCode(); } boolean compare(Object o1, Object o2) { if (o1 == null && o2 == null) return true; if (o1 != null) return o1.equals(o2); return o2.equals(o1); } public boolean equals(Object object) { if (this == object) return true; if (object == null) return false; if (object.getClass() != this.getClass()) return false; ObjectClass oc = (ObjectClass)object; if (!compare(oid, oc.oid)) return false; if (!compare(names, oc.names)) return false; if (!compare(description, oc.description)) return false; if (obsolete != oc.obsolete) return false; if (!compare(superClasses, oc.superClasses)) return false; if (!compare(type, oc.type)) return false; if (!compare(requiredAttributes, oc.requiredAttributes)) return false; if (!compare(optionalAttributes, oc.optionalAttributes)) return false; return true; } boolean equals(Object o1, Object o2) { if (o1 == null && o2 == null) return true; if (o1 != null) return o1.equals(o2); return o2.equals(o1); } public Object clone() throws CloneNotSupportedException { ObjectClass oc = (ObjectClass)super.clone(); oc.oid = oid; oc.names = new ArrayList<String>(); oc.names.addAll(names); oc.description = description; oc.obsolete = obsolete; oc.superClasses = new ArrayList<String>(); oc.superClasses.addAll(superClasses); oc.type = type; oc.requiredAttributes = new ArrayList<String>(); oc.requiredAttributes.addAll(requiredAttributes); oc.normalizedRequiredAttributes = new HashSet<String>(); oc.normalizedRequiredAttributes.addAll(normalizedRequiredAttributes); oc.optionalAttributes = new ArrayList<String>(); oc.optionalAttributes.addAll(optionalAttributes); oc.normalizedOptionalAttributes = new HashSet<String>(); oc.normalizedOptionalAttributes.addAll(normalizedOptionalAttributes); return oc; } public int compareTo(Object object) { if (!(object instanceof ObjectClass)) return 0; ObjectClass oc = (ObjectClass)object; return oid.compareTo(oc.getOid()); } public String toString() { return toString(false); } public String toString(boolean multiLine) { StringWriter sw = new StringWriter(); PrintWriter out = new PrintWriter(sw); out.print(oid); if (multiLine) out.println(); if (names.size() == 1) { if (multiLine) out.print(" "); out.print(" NAME '"+names.iterator().next()+"'"); if (multiLine) out.println(); } else if (names.size() > 1) { if (multiLine) out.print(" "); out.print(" NAME ( "); for (String name : names) { out.print("'" + name + "' "); } out.print(")"); if (multiLine) out.println(); } if (description != null) { if (multiLine) out.print(" "); out.print(" DESC '"+escape(description)+"'"); if (multiLine) out.println(); } if (obsolete) { if (multiLine) out.print(" "); out.print(" OBSOLETE"); if (multiLine) out.println(); } if (superClasses.size() == 1) { if (multiLine) out.print(" "); out.print(" SUP "+superClasses.iterator().next()); if (multiLine) out.println(); } else if (superClasses.size() > 1) { if (multiLine) out.print(" "); out.print(" SUP ( "); for (Iterator i=superClasses.iterator(); i.hasNext(); ) { String name = (String)i.next(); out.print(name); if (i.hasNext()) out.print(" $ "); } out.print(" )"); if (multiLine) out.println(); } if (!STRUCTURAL.equals(type)) { if (multiLine) out.print(" "); out.print(" "+type); if (multiLine) out.println(); } if (requiredAttributes.size() == 1) { if (multiLine) out.print(" "); out.print(" MUST "+requiredAttributes.iterator().next()); if (multiLine) out.println(); } else if (requiredAttributes.size() > 1) { if (multiLine) out.print(" "); out.print(" MUST ( "); for (Iterator i=requiredAttributes.iterator(); i.hasNext(); ) { String name = (String)i.next(); out.print(name); if (i.hasNext()) out.print(" $ "); } out.print(" )"); if (multiLine) out.println(); } if (optionalAttributes.size() == 1) { if (multiLine) out.print(" "); out.print(" MAY "+optionalAttributes.iterator().next()); if (multiLine) out.println(); } else if (optionalAttributes.size() > 1) { if (multiLine) out.print(" "); out.print(" MAY ( "); for (Iterator i=optionalAttributes.iterator(); i.hasNext(); ) { String name = (String)i.next(); out.print(name); if (i.hasNext()) out.print(" $ "); } out.print(" )"); if (multiLine) out.println(); } return sw.toString(); } public static String escape(String s) { StringBuilder sb = new StringBuilder(); for (int i=0; i<s.length(); i++) { char c = s.charAt(i); if (c == '\'' || c == '\\') { sb.append('\\'); sb.append(toHex(c)); } else { sb.append(c); } } return sb.toString(); } public static String toHex(char c) { String s = Integer.toHexString(c); return s.length() == 1 ? '0'+s : s; } }