001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.xbean.propertyeditor;
018
019import java.beans.PropertyEditor;
020import java.util.Iterator;
021import java.util.LinkedList;
022import java.util.List;
023import java.util.StringTokenizer;
024import java.util.Collection;
025import java.util.Properties;
026import java.util.Map;
027import java.util.LinkedHashMap;
028import java.io.ByteArrayInputStream;
029import java.io.IOException;
030import java.io.ByteArrayOutputStream;
031
032/**
033 * @version $Rev: 6680 $ $Date: 2005-12-24T04:38:27.427468Z $
034 */
035public final class CollectionUtil {
036    public static List toList(String text, PropertyEditor componentEditor) {
037        if (text.length() == 0) {
038            return null;
039        }
040
041        // text may be surrounded with [ and ]
042        if (text.startsWith("[") && text.endsWith("]")) {
043            text = text.substring(1, text.length() - 1).trim();
044        }
045
046        List list = new LinkedList();
047
048        if (text.length() > 0) {
049            StringTokenizer stok = new StringTokenizer(text, ",");
050            while (stok.hasMoreTokens()) {
051                String innerText = stok.nextToken();
052                Object value = componentToObject(innerText, componentEditor);
053                list.add(value);
054            }
055        }
056
057        return list;
058    }
059
060    public static String toString(Collection values, PropertyEditor componentEditor) {
061        if (values.size() == 0) {
062            return "[]";
063        }
064
065        StringBuffer result = new StringBuffer();
066        result.append("[");
067        int i = 0;
068        for (Iterator iterator = values.iterator(); iterator.hasNext();) {
069            Object object = iterator.next();
070            String text = componentToString(object, componentEditor);
071
072            if (i > 0) {
073                result.append(",");
074            }
075            result.append(text);
076            i++;
077        }
078        result.append("]");
079        return result.toString();
080    }
081
082    public static final Map toMap(String text, PropertyEditor keyEditor, PropertyEditor valueEditor) {
083        Properties properties = new Properties();
084        try {
085            ByteArrayInputStream stream = new ByteArrayInputStream(text.getBytes());
086            properties.load(stream);
087        } catch (IOException e) {
088            // any errors here are just a property exception
089            throw new PropertyEditorException(e);
090        }
091
092        // run the properties through the editors
093        Map map = new LinkedHashMap(properties.size());
094        for (Iterator iterator = properties.entrySet().iterator(); iterator.hasNext();) {
095            Map.Entry entry = (Map.Entry) iterator.next();
096            String keyText = (String) entry.getKey();
097            String valueText = (String) entry.getValue();
098
099            Object keyObject = componentToObject(keyText, keyEditor);
100            Object valueObject = componentToObject(valueText, valueEditor);
101
102            map.put(keyObject, valueObject);
103        }
104        return map;
105    }
106
107    public static final String toString(Map map, PropertyEditor keyEditor, PropertyEditor valueEditor) {
108        // run the properties through the editors
109        Properties properties = new Properties();
110        for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
111            Map.Entry entry = (Map.Entry) iterator.next();
112            Object keyObject = entry.getKey();
113            Object valueObject = entry.getValue();
114
115            String keyText = componentToString(keyObject, keyEditor);
116            String valueText = componentToString(valueObject, valueEditor);
117
118            properties.setProperty(keyText, valueText);
119        }
120
121        // write using the properties object
122        try {
123            ByteArrayOutputStream out = new ByteArrayOutputStream();
124            properties.store(out, null);
125            String text = new String(out.toByteArray());
126            return text;
127        } catch (IOException e) {
128            // any errors here are just a property exception
129            throw new PropertyEditorException(e);
130        }
131    }
132
133    private static final String componentToString(Object value, PropertyEditor componentEditor) {
134        if (value == null) {
135            return null;
136        }
137        if (componentEditor instanceof Converter) {
138            Converter converter = (Converter) componentEditor;
139            Class type = converter.getType();
140            if (!type.isInstance(value)) {
141                throw new PropertyEditorException("Value is not an instance of " + type.getSimpleName() + ": " + value.getClass().getName());
142            }
143            return converter.toString(value);
144        } else {
145            componentEditor.setValue(value);
146            String text = componentEditor.getAsText();
147            return text;
148        }
149    }
150
151    private static final Object componentToObject(String text, PropertyEditor componentEditor) {
152        if (text == null) {
153            return null;
154        }
155
156        if (componentEditor instanceof Converter) {
157            Converter converter = (Converter) componentEditor;
158            Object value = converter.toObject(text.trim());
159            return value;
160        } else {
161            componentEditor.setAsText(text);
162            Object value = componentEditor.getValue();
163            return value;
164        }
165    }
166}