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     */
017    package org.apache.xbean.propertyeditor;
018    
019    import java.beans.PropertyEditor;
020    import java.util.Iterator;
021    import java.util.LinkedList;
022    import java.util.List;
023    import java.util.StringTokenizer;
024    import java.util.Collection;
025    import java.util.Properties;
026    import java.util.Map;
027    import java.util.LinkedHashMap;
028    import java.io.ByteArrayInputStream;
029    import java.io.IOException;
030    import java.io.ByteArrayOutputStream;
031    
032    /**
033     * @version $Rev: 6680 $ $Date: 2005-12-24T04:38:27.427468Z $
034     */
035    public 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    }