/* * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) 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: * Nuxeo - initial API and implementation * * $Id$ */ package org.eclipse.ecr.core.schema.types; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.ecr.core.schema.TypeRef; /** * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> * */ @SuppressWarnings({ "SuppressionAnnotation" }) public class ListTypeImpl extends AbstractType implements ListType { private static final long serialVersionUID = 6443946870580167862L; protected static final String DEFAULT_VALUE_SEPARATOR = " "; protected final TypeRef<? extends Type> type; protected final Field field; //TODO: should be removed. use field.defaultvalue instead protected String defaultValue; protected int minOccurs; protected int maxOccurs; protected boolean isArray = false; public ListTypeImpl(String schema, String name, TypeRef<? extends Type> type, String fieldName, String defaultValue, int minOccurs, int maxOccurs) { super(null, schema, name); if (fieldName == null) { isArray = true; fieldName = "item"; } this.type = type; field = new FieldImpl(QName.valueOf(fieldName), getRef(), type); this.minOccurs = minOccurs; this.maxOccurs = maxOccurs; this.defaultValue = defaultValue; } public ListTypeImpl(String schema, String name, Type type) { this(schema, name, type.getRef(), null, null, 0, -1); } public ListTypeImpl(String schema, String name, Type type, String defaultValue) { this(schema, name, type.getRef(), null, defaultValue, 0, -1); } public ListTypeImpl(String schema, String name, Type type, String fieldName, String defaultValue, int minOccurs, int maxOccurs) { this(schema, name, type.getRef(), fieldName, defaultValue, minOccurs, maxOccurs); } public ListTypeImpl(String schema, String name, TypeRef<? extends Type> type) { this(schema, name, type, null, null, 0, -1); } public ListTypeImpl(String schema, String name, TypeRef<? extends Type> type, String defaultValue) { this(schema, name, type, null, defaultValue, 0, -1); } @Override public void setLimits(int minOccurs, int maxOccurs) { this.minOccurs = minOccurs; this.maxOccurs = maxOccurs; } @Override public void setDefaultValue(String value) { defaultValue = value; } @Override public String getFieldName() { return field.getName().getLocalName(); } @Override public Type getFieldType() { return field.getType(); } @Override public Field getField() { return field; } @Override public Object getDefaultValue() { return type.get().decode(defaultValue); } public Type getType() { return type.get(); } @Override public int getMinCount() { return minOccurs; } @Override public int getMaxCount() { return maxOccurs; } @Override public boolean isListType() { return true; } @Override public Object decode(String string) { // XXX: OG: I do not really know how this is suppose to work // I need this to decode default values and I could // not find how XMLSchema defines default values for sequences thus the // following naive splitting of the string representation of the default // value if (string != null) { List<Object> decoded = new ArrayList<Object>(); Type t = type.get(); for (String component : string.split(DEFAULT_VALUE_SEPARATOR)) { decoded.add(t.decode(component)); } return decoded; } else { return null; } } @Override @SuppressWarnings("rawtypes") public boolean validate(Object object) throws TypeException { if (object == null && isNotNull()) { return false; } if (object == null) { return true; } if (object instanceof Collection) { return validateCollection((Collection) object); } else if (object.getClass().isArray()) { return validateArray((Object[]) object); } return false; } protected boolean validateArray(Object[] array) { return true; // TODO } @SuppressWarnings("rawtypes") protected boolean validateCollection(Collection col) { return true; // TODO } @Override public Object newInstance() { Object defaultValue = this.defaultValue; if (defaultValue != null) { return defaultValue; } else { // XXX AT: maybe use the type to be more specific on list elements return new ArrayList<Object>(); } } @Override @SuppressWarnings("unchecked") public Object convert(Object object) throws TypeException { if (object instanceof List) { List list = (List) object; Type t = type.get(); for (int i = 0, len = list.size(); i < len; i++) { Object value = list.get(i); list.set(i, t.convert(value)); } return object; } throw new TypeException("Incompatible object: " + object.getClass() + " for type " + getName()); } @Override public TypeRef<ListType> getRef() { return new TypeRef<ListType>(schema, name, this); } @Override public boolean isArray() { return isArray; } @Override public boolean isScalarList() { return field.getType().isSimpleType(); } }