001    /*
002     * JBoss DNA (http://www.jboss.org/dna)
003     * See the COPYRIGHT.txt file distributed with this work for information
004     * regarding copyright ownership.  Some portions may be licensed
005     * to Red Hat, Inc. under one or more contributor license agreements.
006     * See the AUTHORS.txt file in the distribution for a full listing of 
007     * individual contributors. 
008     *
009     * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010     * is licensed to you under the terms of the GNU Lesser General Public License as
011     * published by the Free Software Foundation; either version 2.1 of
012     * the License, or (at your option) any later version.
013     *
014     * JBoss DNA is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this software; if not, write to the Free
021     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023     */
024    package org.jboss.dna.graph.property.basic;
025    
026    import java.io.File;
027    import java.io.IOException;
028    import java.io.InputStream;
029    import java.io.Reader;
030    import java.io.UnsupportedEncodingException;
031    import java.math.BigDecimal;
032    import java.net.URI;
033    import java.util.Calendar;
034    import java.util.Date;
035    import java.util.UUID;
036    import net.jcip.annotations.Immutable;
037    import org.jboss.dna.common.text.TextDecoder;
038    import org.jboss.dna.common.util.IoUtil;
039    import org.jboss.dna.graph.GraphI18n;
040    import org.jboss.dna.graph.property.Binary;
041    import org.jboss.dna.graph.property.BinaryFactory;
042    import org.jboss.dna.graph.property.DateTime;
043    import org.jboss.dna.graph.property.IoException;
044    import org.jboss.dna.graph.property.Name;
045    import org.jboss.dna.graph.property.Path;
046    import org.jboss.dna.graph.property.PropertyType;
047    import org.jboss.dna.graph.property.Reference;
048    import org.jboss.dna.graph.property.ValueFactory;
049    import org.jboss.dna.graph.property.ValueFormatException;
050    
051    /**
052     * An abstract {@link BinaryFactory} implementation that contains many general methods that are likely to be appropriate for many
053     * concrete implementations.
054     * 
055     * @author Randall Hauch
056     * @author John Verhaeg
057     */
058    @Immutable
059    public abstract class AbstractBinaryValueFactory extends AbstractValueFactory<Binary> implements BinaryFactory {
060    
061        private static final String CHAR_SET_NAME = "UTF-8";
062    
063        protected AbstractBinaryValueFactory( TextDecoder decoder,
064                                              ValueFactory<String> stringValueFactory ) {
065            super(PropertyType.BINARY, decoder, stringValueFactory);
066        }
067    
068        /**
069         * {@inheritDoc}
070         */
071        public Binary create( String value ) {
072            if (value == null) return null;
073            try {
074                return create(value.getBytes(CHAR_SET_NAME));
075            } catch (UnsupportedEncodingException err) {
076                throw new ValueFormatException(value, getPropertyType(),
077                                               GraphI18n.errorConvertingType.text(String.class.getSimpleName(),
078                                                                                  Binary.class.getSimpleName(),
079                                                                                  value), err);
080            }
081        }
082    
083        /**
084         * {@inheritDoc}
085         */
086        public Binary create( String value,
087                              TextDecoder decoder ) {
088            if (value == null) return null;
089            return create(getDecoder(decoder).decode(value));
090        }
091    
092        /**
093         * {@inheritDoc}
094         */
095        public Binary create( int value ) {
096            // Convert the value to a string, then to a binary ...
097            return create(this.getStringValueFactory().create(value));
098        }
099    
100        /**
101         * {@inheritDoc}
102         */
103        public Binary create( long value ) {
104            // Convert the value to a string, then to a binary ...
105            return create(this.getStringValueFactory().create(value));
106        }
107    
108        /**
109         * {@inheritDoc}
110         */
111        public Binary create( boolean value ) {
112            // Convert the value to a string, then to a binary ...
113            return create(this.getStringValueFactory().create(value));
114        }
115    
116        /**
117         * {@inheritDoc}
118         */
119        public Binary create( float value ) {
120            // Convert the value to a string, then to a binary ...
121            return create(this.getStringValueFactory().create(value));
122        }
123    
124        /**
125         * {@inheritDoc}
126         */
127        public Binary create( double value ) {
128            // Convert the value to a string, then to a binary ...
129            return create(this.getStringValueFactory().create(value));
130        }
131    
132        /**
133         * {@inheritDoc}
134         */
135        public Binary create( BigDecimal value ) {
136            // Convert the value to a string, then to a binary ...
137            return create(this.getStringValueFactory().create(value));
138        }
139    
140        /**
141         * {@inheritDoc}
142         */
143        public Binary create( Calendar value ) {
144            // Convert the value to a string, then to a binary ...
145            return create(this.getStringValueFactory().create(value));
146        }
147    
148        /**
149         * {@inheritDoc}
150         */
151        public Binary create( Date value ) {
152            // Convert the value to a string, then to a binary ...
153            return create(this.getStringValueFactory().create(value));
154        }
155    
156        /**
157         * {@inheritDoc}
158         * 
159         * @see org.jboss.dna.graph.property.ValueFactory#create(org.jboss.dna.graph.property.DateTime)
160         */
161        public Binary create( DateTime value ) throws ValueFormatException {
162            // Convert the value to a string, then to a binary ...
163            return create(this.getStringValueFactory().create(value));
164        }
165    
166        /**
167         * {@inheritDoc}
168         */
169        public Binary create( Name value ) {
170            // Convert the value to a string, then to a binary ...
171            return create(this.getStringValueFactory().create(value));
172        }
173    
174        /**
175         * {@inheritDoc}
176         */
177        public Binary create( Path value ) {
178            // Convert the value to a string, then to a binary ...
179            return create(this.getStringValueFactory().create(value));
180        }
181    
182        /**
183         * {@inheritDoc}
184         */
185        public Binary create( Reference value ) {
186            // Convert the value to a string, then to a binary ...
187            return create(this.getStringValueFactory().create(value));
188        }
189    
190        /**
191         * {@inheritDoc}
192         */
193        public Binary create( URI value ) {
194            // Convert the value to a string, then to a binary ...
195            return create(this.getStringValueFactory().create(value));
196        }
197    
198        /**
199         * {@inheritDoc}
200         * 
201         * @see org.jboss.dna.graph.property.ValueFactory#create(java.util.UUID)
202         */
203        public Binary create( UUID value ) {
204            // Convert the value to a string, then to a binary ...
205            return create(this.getStringValueFactory().create(value));
206        }
207    
208        /**
209         * {@inheritDoc}
210         * 
211         * @see org.jboss.dna.graph.property.ValueFactory#create(org.jboss.dna.graph.property.Binary)
212         */
213        public Binary create( Binary value ) throws ValueFormatException, IoException {
214            return value;
215        }
216    
217        /**
218         * {@inheritDoc}
219         */
220        public Binary create( InputStream stream,
221                              long approximateLength ) throws IoException {
222            if (stream == null) return null;
223            try {
224                byte[] value = IoUtil.readBytes(stream);
225                return create(value);
226            } catch (IOException err) {
227                throw new IoException(GraphI18n.errorConvertingIo.text(InputStream.class.getSimpleName(),
228                                                                       Binary.class.getSimpleName()), err);
229            }
230        }
231    
232        /**
233         * {@inheritDoc}
234         */
235        public Binary create( Reader reader,
236                              long approximateLength ) throws IoException {
237            if (reader == null) return null;
238            // Convert the value to a string, then to a binary ...
239            try {
240                String value = IoUtil.read(reader);
241                return create(this.getStringValueFactory().create(value));
242            } catch (IOException err) {
243                throw new IoException(GraphI18n.errorConvertingIo.text(Reader.class.getSimpleName(), Binary.class.getSimpleName()),
244                                      err);
245            }
246        }
247    
248        /**
249         * {@inheritDoc}
250         * 
251         * @see org.jboss.dna.graph.property.BinaryFactory#create(java.io.File)
252         */
253        public Binary create( File file ) throws ValueFormatException, IoException {
254            if (file == null) return null;
255            if (!file.canRead()) return null;
256            if (!file.isFile()) return null;
257            try {
258                byte[] value = IoUtil.readBytes(file);
259                return create(value);
260            } catch (IOException err) {
261                throw new IoException(GraphI18n.errorConvertingIo.text(file, Binary.class.getSimpleName()), err);
262            }
263        }
264    
265        /**
266         * {@inheritDoc}
267         * <p>
268         * This implementation does not manage or share the in-memory binary values, so this implementation is identical to calling
269         * {@link #create(Reader, long)}.
270         * </p>
271         * 
272         * @see org.jboss.dna.graph.property.BinaryFactory#create(java.io.Reader, long, byte[])
273         */
274        public Binary create( Reader reader,
275                              long approximateLength,
276                              byte[] secureHash ) throws ValueFormatException, IoException {
277            return create(reader, approximateLength);
278        }
279    
280        /**
281         * {@inheritDoc}
282         * <p>
283         * This implementation does not manage or share the in-memory binary values, so this implementation is identical to calling
284         * {@link #create(InputStream, long)}.
285         * </p>
286         * 
287         * @see org.jboss.dna.graph.property.BinaryFactory#create(java.io.InputStream, long, byte[])
288         */
289        public Binary create( InputStream stream,
290                              long approximateLength,
291                              byte[] secureHash ) throws ValueFormatException, IoException {
292            return create(stream, approximateLength);
293        }
294    
295        /**
296         * {@inheritDoc}
297         * <p>
298         * This method always returns null, since the in-memory binary values are not managed or shared.
299         * </p>
300         * 
301         * @see org.jboss.dna.graph.property.BinaryFactory#find(byte[])
302         */
303        public Binary find( byte[] secureHash ) {
304            return null;
305        }
306    
307        /**
308         * {@inheritDoc}
309         */
310        @Override
311        protected Binary[] createEmptyArray( int length ) {
312            return new Binary[length];
313        }
314    }