001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.core.util;
011:
012: import org.mmbase.bridge.*;
013: import org.mmbase.datatypes.*;
014: import org.mmbase.core.CoreField;
015: import java.util.*;
016:
017: /**
018:
019: * @since MMBase-1.8
020: */
021: public class Fields {
022: public final static int STATE_MINVALUE = 0;
023: public final static int STATE_MAXVALUE = 3;
024: private final static String[] STATES = { "unknown", "virtual",
025: "unknown", "persistent", "system", "systemvirtual" };
026:
027: public final static int TYPE_MINVALUE = 1;
028: public final static int TYPE_MAXVALUE = 12;
029: private final static String[] TYPES = { "UNKNOWN", "STRING",
030: "INTEGER", "UNKNOWN", "BINARY" /* BYTE */, "FLOAT",
031: "DOUBLE", "LONG", "XML", "NODE", "DATETIME", "BOOLEAN",
032: "LIST" };
033:
034: /**
035: * Returns an instance of a CoreField based on the type, with state 'SYSTEM', and a basic datatype assigned.
036: * @param name The name of the field
037: * @param type the MMBase basic field type, one of the {@link Field} TYPE constants. Specifying {@link Field#TYPE_LIST},
038: * may give unpredictable results.
039: */
040: public static CoreField createSystemField(String name, int type) {
041: return createField(name, type, Field.TYPE_UNKNOWN,
042: Field.STATE_SYSTEM, null);
043: }
044:
045: /**
046: * Returns an instance of a CoreField based on the type and state.
047: * @param name The name of the field
048: * @param type the MMBase basic field type, one of the {@link Field} TYPE constants.
049: * @param listItemType the MMBase type for items of a list (if type is {@link Field#TYPE_LIST}).
050: * @param state the MMBase field state, one of the {@link Field} STATE constants.
051: * @param dataType the dataType to use for validating the field data. If <code>null</code>, a default datatype is assigned
052: */
053: public static CoreField createField(String name, int type,
054: int listItemType, int state, DataType dataType) {
055: if (dataType == null) {
056: if (type == Field.TYPE_LIST) {
057: dataType = (DataType) DataTypes.getListDataType(
058: listItemType).clone();
059: } else {
060: dataType = (DataType) DataTypes.getDataType(type)
061: .clone();
062: }
063: }
064: return new org.mmbase.module.corebuilders.FieldDefs(name, type,
065: listItemType, state, dataType);
066: }
067:
068: /**
069: * Provide a description for the specified type.
070: * Useful for debugging, errors or presenting GUI info.
071: * @param type the type to get the description of
072: * @return the description of the type.
073: */
074: public static String getTypeDescription(int type) {
075: if (type < TYPE_MINVALUE || type > TYPE_MAXVALUE) {
076: return TYPES[0];
077: }
078:
079: return TYPES[type - TYPE_MINVALUE + 1];
080: }
081:
082: /**
083: * Provide a description for the specified state.
084: * Useful for debugging, errors or presenting GUI info.
085: * @param state the state to get the description of
086: * @return the description of the state.
087: */
088: public static String getStateDescription(int state) {
089: if (state < STATE_MINVALUE || state > STATE_MAXVALUE) {
090: return STATES[0];
091: }
092: return STATES[state - STATE_MINVALUE + 1];
093: }
094:
095: /**
096: * Provide an id for the specified mmbase state description.
097: * @param state the state description to get the id of
098: * @return the id of the state.
099: */
100: public static int getState(String state) {
101: if (state == null)
102: return Field.STATE_UNKNOWN;
103: state = state.toLowerCase();
104: if (state.equals("persistent"))
105: return Field.STATE_PERSISTENT;
106: if (state.equals("virtual"))
107: return Field.STATE_VIRTUAL;
108: if (state.equals("systemvirtual"))
109: return Field.STATE_SYSTEM_VIRTUAL;
110: if (state.equals("system"))
111: return Field.STATE_SYSTEM;
112: return Field.STATE_UNKNOWN;
113: }
114:
115: /**
116: * Provide an id for the specified mmbase type description
117: * @param type the type description to get the id of
118: * @return the id of the type.
119: */
120: public static int getType(String type) {
121: if (type == null)
122: return Field.TYPE_UNKNOWN;
123: // XXX: deprecated VARCHAR
124: type = type.toUpperCase();
125: if (type.equals("VARCHAR"))
126: return Field.TYPE_STRING;
127: if (type.equals("STRING"))
128: return Field.TYPE_STRING;
129: if (type.equals("XML"))
130: return Field.TYPE_XML;
131: if (type.equals("INTEGER"))
132: return Field.TYPE_INTEGER;
133: if (type.equals("BYTE"))
134: return Field.TYPE_BINARY;
135: if (type.equals("BINARY"))
136: return Field.TYPE_BINARY;
137: if (type.equals("FLOAT"))
138: return Field.TYPE_FLOAT;
139: if (type.equals("DOUBLE"))
140: return Field.TYPE_DOUBLE;
141: if (type.equals("LONG"))
142: return Field.TYPE_LONG;
143: if (type.equals("NODE"))
144: return Field.TYPE_NODE;
145: if (type.equals("DATETIME"))
146: return Field.TYPE_DATETIME;
147: if (type.equals("BOOLEAN"))
148: return Field.TYPE_BOOLEAN;
149: if (type.startsWith("LIST"))
150: return Field.TYPE_LIST;
151: return Field.TYPE_UNKNOWN;
152: }
153:
154: /**
155: * Determines the MMBase type of a specified class. The MMBase base type is sue by the storage layer to
156: * determine how to store a field.
157: * If the base type cannot be determined from the class, the value returned is {@link Field#TYPE_UNKNOWN}.
158: * @param classType
159: * @return an MMBase base type constant
160: */
161: public static int classToType(Class classType) {
162: if (classType == null) {
163: return Field.TYPE_UNKNOWN;
164: } else if (classType.isArray()
165: && classType.getComponentType() == Byte.TYPE) {
166: return Field.TYPE_BINARY;
167: } else if (classType == Integer.class
168: || classType == Integer.TYPE) {
169: return Field.TYPE_INTEGER;
170: } else if (classType == Long.class || classType == Long.TYPE) {
171: return Field.TYPE_LONG;
172: } else if (classType == Double.class
173: || classType == Double.TYPE) {
174: return Field.TYPE_DOUBLE;
175: } else if (classType == Float.class || classType == Float.TYPE) {
176: return Field.TYPE_FLOAT;
177: } else if (classType == Boolean.class
178: || classType == Boolean.TYPE) {
179: return Field.TYPE_BOOLEAN;
180: } else if (classType == String.class) {
181: return Field.TYPE_STRING;
182: } else if (org.w3c.dom.Node.class.isAssignableFrom(classType)) {
183: return Field.TYPE_XML;
184: } else if (Node.class.isAssignableFrom(classType)) {
185: return Field.TYPE_NODE;
186: } else if (Date.class.isAssignableFrom(classType)) {
187: return Field.TYPE_DATETIME;
188: } else if (List.class.isAssignableFrom(classType)) {
189: return Field.TYPE_LIST;
190: } else {
191: return Field.TYPE_UNKNOWN;
192: }
193: }
194:
195: /**
196: * Determines the class for a specified MMBase base type.
197: * If the value is {@link Field#TYPE_UNKNOWN}), the method returns <code>null</code>.
198: * @param type
199: * @return an MMBase base type constant
200: */
201: public static Class typeToClass(int type) {
202: switch (type) {
203: case Field.TYPE_STRING:
204: return String.class;
205: case Field.TYPE_INTEGER:
206: return Integer.class;
207: case Field.TYPE_BINARY:
208: return byte[].class;
209: case Field.TYPE_FLOAT:
210: return Float.class;
211: case Field.TYPE_DOUBLE:
212: return Double.class;
213: case Field.TYPE_LONG:
214: return Long.class;
215: case Field.TYPE_XML:
216: return org.w3c.dom.Document.class;
217: case Field.TYPE_NODE:
218: return Node.class;
219: case Field.TYPE_DATETIME:
220: return java.util.Date.class;
221: case Field.TYPE_BOOLEAN:
222: return Boolean.class;
223: case Field.TYPE_LIST:
224: return List.class;
225: default:
226: return null;
227: }
228: }
229:
230: public static void sort(List<CoreField> fields, int order) {
231: Collections.sort(fields, new FieldComparator(order));
232: }
233:
234: /**
235: * Comparator to sort CoreFields by creation order, or by position
236: * specified in one of the GUIPos fields.
237: */
238: private static class FieldComparator implements
239: Comparator<CoreField> {
240:
241: private int order = NodeManager.ORDER_CREATE;
242:
243: /**
244: * Constrcuts a comparator to sort fields on teh specifie dorder
245: * @param order one of NodeManager.ORDER_CREATE, NodeManager.ORDER_EDIT, NodeManager.ORDER_LIST, NodeManager.ORDER_SEARCH
246: */
247: FieldComparator(int order) {
248: this .order = order;
249: }
250:
251: /**
252: * Retrieve the postion of a CoreField object according to the order to sort on
253: */
254: private int getPos(CoreField o) {
255: switch (order) {
256: case NodeManager.ORDER_EDIT: {
257: return o.getEditPosition();
258: }
259: case NodeManager.ORDER_LIST: {
260: return o.getListPosition();
261: }
262: case NodeManager.ORDER_SEARCH: {
263: return o.getSearchPosition();
264: }
265: default: {
266: return o.getStoragePosition();
267: }
268: }
269: }
270:
271: /**
272: * Compare two objects (should be CoreFields)
273: */
274: public int compare(CoreField o1, CoreField o2) {
275: int pos1 = getPos(o1);
276: int pos2 = getPos(o2);
277:
278: if (pos1 < pos2) {
279: return -1;
280: } else if (pos1 > pos2) {
281: return 1;
282: } else {
283: return 0;
284: }
285: }
286: }
287:
288: }
|