001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. 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,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.conf;
020:
021: import java.io.BufferedInputStream;
022: import java.io.BufferedOutputStream;
023: import java.io.File;
024: import java.io.FileOutputStream;
025: import java.io.IOException;
026: import java.io.ObjectInputStream;
027: import java.io.ObjectOutputStream;
028: import java.io.OutputStream;
029: import java.net.URL;
030: import java.util.Enumeration;
031:
032: import org.apache.openjpa.lib.conf.Configurable;
033: import org.apache.openjpa.lib.conf.Configuration;
034: import org.apache.openjpa.lib.conf.Configurations;
035: import org.apache.openjpa.lib.log.Log;
036: import org.apache.openjpa.lib.util.Localizer;
037: import org.apache.openjpa.util.InternalException;
038:
039: /**
040: * Default {@link CacheMarshaller} implementation that writes data
041: * to a specified file and reads data from a specified file or URL.
042: *
043: * @since 1.1.0
044: */
045: public class CacheMarshallerImpl implements CacheMarshaller,
046: Configurable {
047:
048: private static final Localizer _loc = Localizer
049: .forPackage(CacheMarshallerImpl.class);
050:
051: private String _id;
052: private ValidationPolicy _validationPolicy;
053: private OpenJPAConfiguration _conf;
054: private Log _log;
055: private File _outputFile;
056: private URL _inputURL;
057:
058: // temporary storage for resource location specification
059: private String _inputResourceLocation;
060:
061: private boolean _consumeErrors = true;
062:
063: public Object load() {
064: if (_inputURL == null) {
065: _log.trace(_loc.get("cache-marshaller-no-inputs", getId()));
066: return null;
067: }
068:
069: Object o = null;
070: ObjectInputStream in = null;
071: try {
072: in = new ObjectInputStream(new BufferedInputStream(
073: _inputURL.openStream()));
074:
075: o = in.readObject();
076: o = _validationPolicy.getValidData(o);
077:
078: if (o != null && o.getClass().isArray()) {
079: Object[] array = (Object[]) o;
080: for (int i = 0; i < array.length; i++)
081: configure(array[i]);
082: } else {
083: configure(o);
084: }
085:
086: if (_log.isTraceEnabled())
087: _log.trace(_loc.get("cache-marshaller-loaded",
088: o == null ? null : o.getClass().getName(),
089: _inputURL));
090: } catch (Exception e) {
091: if (_consumeErrors) {
092: if (_log.isWarnEnabled())
093: _log.warn(_loc.get(
094: "cache-marshaller-load-exception",
095: _inputURL), e);
096: } else {
097: throw new InternalException(_loc.get(
098: "cache-marshaller-load-exception", _inputURL),
099: e);
100: }
101: } finally {
102: if (in != null)
103: try {
104: in.close();
105: } catch (IOException e) {
106: }
107: }
108:
109: return o;
110: }
111:
112: private void configure(Object o) {
113: if (o instanceof Configurable) {
114: ((Configurable) o).setConfiguration(_conf);
115: ((Configurable) o).startConfiguration();
116: ((Configurable) o).endConfiguration();
117: }
118: }
119:
120: public void store(Object o) {
121: if (_outputFile == null) {
122: _log.trace(_loc.get("cache-marshaller-no-output-file",
123: getId()));
124: return;
125: }
126: OutputStream out = null;
127: try {
128: out = new FileOutputStream(_outputFile);
129: ObjectOutputStream oos = new ObjectOutputStream(
130: new BufferedOutputStream(out));
131: Object toStore = _validationPolicy.getCacheableData(o);
132: oos.writeObject(toStore);
133: oos.flush();
134: out.flush();
135: if (_log.isTraceEnabled())
136: _log.trace(_loc.get("cache-marshaller-stored", o
137: .getClass().getName(), _outputFile));
138: } catch (Exception e) {
139: if (_consumeErrors) {
140: if (_log.isWarnEnabled())
141: _log
142: .warn(
143: _loc
144: .get(
145: "cache-marshaller-store-exception",
146: o.getClass()
147: .getName(),
148: _outputFile), e);
149: } else {
150: throw new InternalException(_loc.get(
151: "cache-marshaller-store-exception", o
152: .getClass().getName(), _outputFile), e);
153: }
154: } finally {
155: if (out != null) {
156: try {
157: out.close();
158: } catch (IOException ioe) {
159: }
160: }
161: }
162: }
163:
164: public void setOutputFile(File file) {
165: _outputFile = file;
166: }
167:
168: public File getOutputFile() {
169: return _outputFile;
170: }
171:
172: public void setInputURL(URL url) {
173: _inputURL = url;
174: }
175:
176: public void setInputResource(String resource) {
177: _inputResourceLocation = resource;
178: }
179:
180: public void setConsumeSerializationErrors(boolean consume) {
181: _consumeErrors = consume;
182: }
183:
184: public String getId() {
185: return _id;
186: }
187:
188: public void setId(String id) {
189: _id = id;
190: }
191:
192: public void setValidationPolicy(String policy)
193: throws InstantiationException, IllegalAccessException {
194: String name = Configurations.getClassName(policy);
195: String props = Configurations.getProperties(policy);
196: _validationPolicy = (ValidationPolicy) Configurations
197: .newInstance(name, _conf, props, null);
198: }
199:
200: public ValidationPolicy getValidationPolicy() {
201: return _validationPolicy;
202: }
203:
204: public void setConfiguration(Configuration conf) {
205: _conf = (OpenJPAConfiguration) conf;
206: _log = conf.getConfigurationLog();
207: }
208:
209: public void startConfiguration() {
210: }
211:
212: public void endConfiguration() {
213: if (_inputResourceLocation != null && _inputURL != null)
214: throw new IllegalStateException(
215: _loc
216: .get(
217: "cache-marshaller-input-url-and-resource-specified")
218: .getMessage());
219: if (_inputResourceLocation != null)
220: setInputUrlFromResourceLocation();
221:
222: if (_validationPolicy == null)
223: throw new IllegalStateException(_loc.get(
224: "cache-marshaller-null-validation-policy",
225: getClass().getName()).getMessage());
226: if (_id == null)
227: throw new IllegalStateException(_loc.get(
228: "cache-marshaller-null-id", getClass().getName())
229: .getMessage());
230: }
231:
232: private void setInputUrlFromResourceLocation() {
233: try {
234: ClassLoader cl = _conf.getClassResolverInstance()
235: .getClassLoader(getClass(), null);
236: for (Enumeration e = cl
237: .getResources(_inputResourceLocation); e
238: .hasMoreElements();) {
239: if (_inputURL == null)
240: _inputURL = (URL) e.nextElement();
241: else
242: throw new IllegalStateException(_loc.get(
243: "cache-marshaller-multiple-resources",
244: getId(), _inputResourceLocation)
245: .getMessage());
246: }
247: } catch (IOException ioe) {
248: IllegalStateException ise = new IllegalStateException(_loc
249: .get("cache-marshaller-bad-url", getId(),
250: _inputResourceLocation).getMessage());
251: ise.initCause(ioe);
252: throw ise;
253: }
254: }
255: }
|