001 /*
002 * $Id: AbstractSerializer.java,v 1.4 2014/01/04 21:56:42 oboehm Exp $
003 *
004 * Copyright (c) 2013 by Oliver Boehm
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 *
018 * (c)reated 30.11.2013 by oliver (ob@oasd.de)
019 */
020
021 package patterntesting.runtime.io;
022
023 import java.io.*;
024 import java.net.URI;
025
026 import org.slf4j.*;
027
028 import patterntesting.runtime.monitor.ClasspathMonitor;
029
030 /**
031 * This is the common superclass for all Serializer casses in PatternTesting.
032 * This class was introduced to be able to abstract from the used XStream
033 * library in the log package. This allows us to declare the xstream library
034 * as "optional" in the POM file.
035 *
036 * @author oliver
037 * @since 1.4 (30.11.2013)
038 */
039 public abstract class AbstractSerializer {
040
041 private static final Logger log = LoggerFactory.getLogger(AbstractSerializer.class);
042 private static final AbstractSerializer instance;
043
044 static {
045 if (isXStreamAvailable()) {
046 instance = new XStreamSerializer();
047 } else {
048 instance = new BinarySerializer();
049 }
050 }
051
052 private static boolean isXStreamAvailable() {
053 String xstreamClassname ="com.thoughtworks.xstream.XStream";
054 URI xstreamURI = ClasspathMonitor.getInstance().whichClass(xstreamClassname);
055 if (xstreamURI == null) {
056 log.debug("{} not found in classpath for serialization.", xstreamClassname);
057 return false;
058 } else {
059 log.debug("{} found in {} for serialization.", xstreamClassname, xstreamURI);
060 return true;
061 }
062 }
063
064 /**
065 * This static method returns an instance of the default serializer.
066 * Normally this is the {@link XStreamSerializer} if the xstream library is
067 * detected in the classpath. If not the {@link BinarySerializer} (which
068 * requires the serialized objects to be {@link Serializable}) will be used
069 * as fallback.
070 *
071 * @return the default serializer
072 */
073 public static AbstractSerializer getInstance() {
074 return instance;
075 }
076
077 /**
078 * Creates the {@link ObjectInputStream} that deserializes a stream of
079 * objects from an InputStream.
080 *
081 * @param in the input stream
082 * @return the object input stream
083 * @throws IOException Signals that an I/O exception has occurred.
084 */
085 public abstract ObjectInputStream createObjectInputStream(InputStream in)
086 throws IOException;
087
088 /**
089 * Creates the {@link ObjectOutputStream} that serializees a stream of
090 * objects to the {@link OutputStream}.
091 *
092 * @param out the output stream
093 * @return the object output stream
094 * @throws IOException Signals that an I/O exception has occurred.
095 */
096 public abstract ObjectOutputStream createObjectOutputStream(OutputStream out)
097 throws IOException;
098
099 /**
100 * Loads a single ojbect from the given file.
101 *
102 * @param file the file
103 * @return the object
104 * @throws IOException Signals that an I/O exception has occurred.
105 * @throws ClassNotFoundException the class not found exception
106 */
107 public Object load(final File file) throws IOException, ClassNotFoundException {
108 InputStream istream = new FileInputStream(file);
109 try {
110 return load(istream);
111 } finally {
112 istream.close();
113 }
114 }
115
116 /**
117 * Loads a single ojbect from the given stream.
118 *
119 * @param in the in
120 * @return the object
121 * @throws IOException Signals that an I/O exception has occurred.
122 * @throws ClassNotFoundException the class not found exception
123 */
124 public Object load(final InputStream in) throws IOException, ClassNotFoundException {
125 ObjectInputStream objStream = this.createObjectInputStream(in);
126 return objStream.readObject();
127 }
128
129 /**
130 * Saves a single object to the given file.
131 *
132 * @param object the object
133 * @param file the file
134 * @throws IOException Signals that an I/O exception has occurred.
135 */
136 public void save(final Object object, final File file) throws IOException {
137 OutputStream ostream = new FileOutputStream(file);
138 try {
139 save(object, ostream);
140 ostream.flush();
141 } finally {
142 ostream.close();
143 }
144 }
145
146 /**
147 * Saves a single object to the given stream.
148 *
149 * @param object the object
150 * @param out the out
151 * @throws IOException Signals that an I/O exception has occurred.
152 */
153 public void save(final Object object, final OutputStream out) throws IOException {
154 ObjectOutputStream objStream = this.createObjectOutputStream(out);
155 objStream.writeObject(object);
156 objStream.flush();
157 }
158
159 }
160