001    /*
002     * JBoss, Home of Professional Open Source.
003     * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004     * as indicated by the @author tags. See the copyright.txt file in the
005     * distribution for a full listing of individual contributors. 
006     *
007     * This is free software; you can redistribute it and/or modify it
008     * under the terms of the GNU Lesser General Public License as
009     * published by the Free Software Foundation; either version 2.1 of
010     * the License, or (at your option) any later version.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this software; if not, write to the Free
019     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021     */
022    package org.jboss.dna.graph.properties.basic;
023    
024    import java.io.IOException;
025    import java.io.InputStream;
026    import java.io.Reader;
027    import java.io.UnsupportedEncodingException;
028    import java.math.BigDecimal;
029    import java.net.URI;
030    import java.util.Calendar;
031    import java.util.Date;
032    import java.util.UUID;
033    import net.jcip.annotations.Immutable;
034    import org.jboss.dna.common.text.TextDecoder;
035    import org.jboss.dna.common.text.TextEncoder;
036    import org.jboss.dna.common.util.CheckArg;
037    import org.jboss.dna.common.util.IoUtil;
038    import org.jboss.dna.common.util.Logger;
039    import org.jboss.dna.graph.GraphI18n;
040    import org.jboss.dna.graph.properties.Binary;
041    import org.jboss.dna.graph.properties.DateTime;
042    import org.jboss.dna.graph.properties.IoException;
043    import org.jboss.dna.graph.properties.Name;
044    import org.jboss.dna.graph.properties.Path;
045    import org.jboss.dna.graph.properties.PropertyType;
046    import org.jboss.dna.graph.properties.Reference;
047    import org.jboss.dna.graph.properties.ValueFactory;
048    import org.jboss.dna.graph.properties.ValueFormatException;
049    
050    /**
051     * The standard {@link ValueFactory} for {@link PropertyType#STRING} values.
052     * 
053     * @author Randall Hauch
054     * @author John Verhaeg
055     */
056    @Immutable
057    public class StringValueFactory extends AbstractValueFactory<String> {
058    
059        private final TextEncoder encoder;
060    
061        public StringValueFactory( TextDecoder decoder,
062                                   TextEncoder encoder ) {
063            super(PropertyType.STRING, decoder, null);
064            CheckArg.isNotNull(encoder, "encoder");
065            this.encoder = encoder;
066        }
067    
068        /**
069         * @return encoder
070         */
071        public TextEncoder getEncoder() {
072            return this.encoder;
073        }
074    
075        /**
076         * {@inheritDoc}
077         */
078        @Override
079        protected ValueFactory<String> getStringValueFactory() {
080            return this;
081        }
082    
083        /**
084         * {@inheritDoc}
085         */
086        public String create( String value ) {
087            return value;
088        }
089    
090        /**
091         * {@inheritDoc}
092         */
093        public String create( String value,
094                              TextDecoder decoder ) {
095            if (value == null) return value;
096            if (decoder == null) decoder = getDecoder();
097            return decoder.decode(value);
098        }
099    
100        /**
101         * {@inheritDoc}
102         */
103        public String create( int value ) {
104            return Integer.toString(value);
105        }
106    
107        /**
108         * {@inheritDoc}
109         */
110        public String create( long value ) {
111            return Long.toString(value);
112        }
113    
114        /**
115         * {@inheritDoc}
116         */
117        public String create( boolean value ) {
118            return Boolean.toString(value);
119        }
120    
121        /**
122         * {@inheritDoc}
123         */
124        public String create( float value ) {
125            return Float.toString(value);
126        }
127    
128        /**
129         * {@inheritDoc}
130         */
131        public String create( double value ) {
132            return Double.toString(value);
133        }
134    
135        /**
136         * {@inheritDoc}
137         */
138        public String create( BigDecimal value ) {
139            if (value == null) return null;
140            return value.toString();
141        }
142    
143        /**
144         * {@inheritDoc}
145         */
146        public String create( Calendar value ) {
147            if (value == null) return null;
148            return new JodaDateTime(value).getString();
149        }
150    
151        /**
152         * {@inheritDoc}
153         */
154        public String create( Date value ) {
155            if (value == null) return null;
156            return new JodaDateTime(value).getString();
157        }
158    
159        /**
160         * {@inheritDoc}
161         * 
162         * @see org.jboss.dna.graph.properties.ValueFactory#create(org.jboss.dna.graph.properties.DateTime)
163         */
164        public String create( DateTime value ) throws ValueFormatException {
165            if (value == null) return null;
166            return value.getString(); // ISO representation
167        }
168    
169        /**
170         * {@inheritDoc}
171         */
172        public String create( Name value ) {
173            if (value == null) return null;
174            return value.getString(getEncoder());
175        }
176    
177        /**
178         * {@inheritDoc}
179         */
180        public String create( Path value ) {
181            if (value == null) return null;
182            return value.getString(getEncoder());
183        }
184    
185        /**
186         * {@inheritDoc}
187         */
188        public String create( Reference value ) {
189            if (value == null) return null;
190            return value.getString(getEncoder());
191        }
192    
193        /**
194         * {@inheritDoc}
195         */
196        public String create( URI value ) {
197            if (value == null) return null;
198            return value.toString();
199        }
200    
201        /**
202         * {@inheritDoc}
203         * 
204         * @see org.jboss.dna.graph.properties.ValueFactory#create(java.util.UUID)
205         */
206        public String create( UUID value ) throws IoException {
207            if (value == null) return null;
208            return value.toString();
209        }
210    
211        /**
212         * {@inheritDoc}
213         */
214        public String create( byte[] value ) {
215            if (value == null) return null;
216            try {
217                return new String(value, "UTF-8");
218            } catch (UnsupportedEncodingException err) {
219                throw new ValueFormatException(value, getPropertyType(),
220                                               GraphI18n.errorConvertingType.text(byte[].class.getSimpleName(),
221                                                                                String.class.getSimpleName(),
222                                                                                value), err);
223            }
224        }
225    
226        /**
227         * {@inheritDoc}
228         * 
229         * @see org.jboss.dna.graph.properties.ValueFactory#create(org.jboss.dna.graph.properties.Binary)
230         */
231        public String create( Binary value ) throws ValueFormatException, IoException {
232            if (value == null) return null;
233            try {
234                value.acquire();
235                InputStream stream = value.getStream();
236                try {
237                    return create(stream, value.getSize());
238                } finally {
239                    try {
240                        stream.close();
241                    } catch (IOException e) {
242                        Logger.getLogger(getClass()).debug(e, "Error closing the stream while converting from Binary to String");
243                    }
244                }
245            } finally {
246                value.release();
247            }
248        }
249    
250        /**
251         * {@inheritDoc}
252         */
253        public String create( InputStream stream,
254                              long approximateLength ) throws IoException {
255            if (stream == null) return null;
256            byte[] value = null;
257            try {
258                value = IoUtil.readBytes(stream);
259                return new String(value, "UTF-8");
260            } catch (UnsupportedEncodingException err) {
261                throw new ValueFormatException(value, getPropertyType(),
262                                               GraphI18n.errorConvertingType.text(InputStream.class.getSimpleName(),
263                                                                                String.class.getSimpleName(),
264                                                                                value), err);
265            } catch (IOException err) {
266                throw new IoException(
267                                      GraphI18n.errorConvertingIo.text(InputStream.class.getSimpleName(), String.class.getSimpleName()),
268                                      err);
269            }
270        }
271    
272        /**
273         * {@inheritDoc}
274         */
275        public String create( Reader reader,
276                              long approximateLength ) throws IoException {
277            if (reader == null) return null;
278            try {
279                return IoUtil.read(reader);
280            } catch (IOException err) {
281                throw new IoException(GraphI18n.errorConvertingIo.text(Reader.class.getSimpleName(), String.class.getSimpleName()), err);
282            }
283        }
284    
285        /**
286         * {@inheritDoc}
287         */
288        @Override
289        protected String[] createEmptyArray( int length ) {
290            return new String[length];
291        }
292    
293    }