/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
package org.apache.openjpa.conf; | |
import java.io.BufferedInputStream; | |
import java.io.BufferedOutputStream; | |
import java.io.File; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.OutputStream; | |
import java.net.URL; | |
import java.util.Enumeration; | |
import java.util.List; | |
import java.util.ArrayList; | |
import org.apache.openjpa.lib.conf.Configurable; | |
import org.apache.openjpa.lib.conf.Configuration; | |
import org.apache.openjpa.lib.conf.Configurations; | |
import org.apache.openjpa.lib.log.Log; | |
import org.apache.openjpa.lib.util.Localizer; | |
import org.apache.openjpa.util.InternalException; | |
/** | |
* Default {@link CacheMarshaller} implementation that writes data | |
* to a specified file and reads data from a specified file or URL. | |
* | |
* @since 1.1.0 | |
*/ | |
public class CacheMarshallerImpl | |
implements CacheMarshaller, Configurable { | |
private static final Localizer _loc = | |
Localizer.forPackage(CacheMarshallerImpl.class); | |
private String _id; | |
private ValidationPolicy _validationPolicy; | |
private OpenJPAConfiguration _conf; | |
private Log _log; | |
private File _outputFile; | |
private URL _inputURL; | |
// temporary storage for resource location specification | |
private String _inputResourceLocation; | |
private boolean _consumeErrors = true; | |
public Object load() { | |
if (_inputURL == null) { | |
_log.trace(_loc.get("cache-marshaller-no-inputs", getId())); | |
return null; | |
} | |
Object o = null; | |
ObjectInputStream in = null; | |
try { | |
in = new ObjectInputStream(new BufferedInputStream( | |
_inputURL.openStream())); | |
o = in.readObject(); | |
o = _validationPolicy.getValidData(o); | |
if (o != null && o.getClass().isArray()) { | |
Object[] array = (Object[]) o; | |
for (int i = 0; i < array.length; i++) | |
configure(array[i]); | |
} else { | |
configure(o); | |
} | |
if (_log.isTraceEnabled()) | |
_log.trace(_loc.get("cache-marshaller-loaded", | |
o == null ? null : o.getClass().getName(), _inputURL)); | |
} catch (Exception e) { | |
if (_consumeErrors) { | |
if (_log.isWarnEnabled()) | |
_log.warn(_loc.get("cache-marshaller-load-exception-ignore", | |
_inputURL), e); | |
} else { | |
throw new InternalException( | |
_loc.get("cache-marshaller-load-exception-fatal", | |
_inputURL), | |
e); | |
} | |
} finally { | |
if (in != null) | |
try { in.close(); } catch (IOException e) { } | |
} | |
return o; | |
} | |
private void configure(Object o) { | |
if (o instanceof Configurable) { | |
((Configurable) o).setConfiguration(_conf); | |
((Configurable) o).startConfiguration(); | |
((Configurable) o).endConfiguration(); | |
} | |
} | |
public void store(Object o) { | |
if (_outputFile == null) { | |
_log.trace(_loc.get("cache-marshaller-no-output-file", getId())); | |
return; | |
} | |
OutputStream out = null; | |
try { | |
out = new FileOutputStream(_outputFile); | |
ObjectOutputStream oos = | |
new ObjectOutputStream(new BufferedOutputStream(out)); | |
Object toStore = _validationPolicy.getCacheableData(o); | |
oos.writeObject(toStore); | |
oos.flush(); | |
out.flush(); | |
if (_log.isTraceEnabled()) | |
_log.trace(_loc.get("cache-marshaller-stored", | |
o.getClass().getName(), _outputFile)); | |
} catch (Exception e) { | |
if (_consumeErrors) { | |
if (_log.isWarnEnabled()) | |
_log.warn(_loc.get("cache-marshaller-store-exception", | |
o.getClass().getName(), _outputFile), e); | |
} else { | |
throw new InternalException( | |
_loc.get("cache-marshaller-store-exception", | |
o.getClass().getName(), _outputFile), | |
e); | |
} | |
} finally { | |
if (out != null) { | |
try { out.close(); } catch (IOException ioe) { } | |
} | |
} | |
} | |
public void setOutputFile(File file) { | |
_outputFile = file; | |
} | |
public File getOutputFile() { | |
return _outputFile; | |
} | |
public void setInputURL(URL url) { | |
_inputURL = url; | |
} | |
public void setInputResource(String resource) { | |
_inputResourceLocation = resource; | |
} | |
public void setConsumeSerializationErrors(boolean consume) { | |
_consumeErrors = consume; | |
} | |
public String getId() { | |
return _id; | |
} | |
public void setId(String id) { | |
_id = id; | |
} | |
public void setValidationPolicy(String policy) | |
throws InstantiationException, IllegalAccessException { | |
String name = Configurations.getClassName(policy); | |
String props = Configurations.getProperties(policy); | |
_validationPolicy = (ValidationPolicy) | |
Configurations.newInstance(name, _conf, props, null); | |
} | |
public ValidationPolicy getValidationPolicy() { | |
return _validationPolicy; | |
} | |
public void setConfiguration(Configuration conf) { | |
_conf = (OpenJPAConfiguration) conf; | |
_log = conf.getConfigurationLog(); | |
} | |
public void startConfiguration() { | |
} | |
public void endConfiguration() { | |
if (_inputResourceLocation != null && _inputURL != null) | |
throw new IllegalStateException( | |
_loc.get("cache-marshaller-input-url-and-resource-specified") | |
.getMessage()); | |
if (_inputResourceLocation != null) | |
setInputUrlFromResourceLocation(); | |
if (_validationPolicy == null) | |
throw new IllegalStateException( | |
_loc.get("cache-marshaller-null-validation-policy", | |
getClass().getName()).getMessage()); | |
if (_id == null) | |
throw new IllegalStateException( | |
_loc.get("cache-marshaller-null-id", | |
getClass().getName()).getMessage()); | |
} | |
private void setInputUrlFromResourceLocation() { | |
try { | |
ClassLoader cl = _conf.getClassResolverInstance() | |
.getClassLoader(getClass(), null); | |
List list = new ArrayList(); | |
for (Enumeration e = cl.getResources(_inputResourceLocation); | |
e.hasMoreElements(); ) | |
list.add(e); | |
if (list.size() > 1) { | |
if (_consumeErrors) { | |
if (_log.isWarnEnabled()) | |
_log.warn(_loc.get( | |
"cache-marshaller-multiple-resources-warn", | |
getId(), _inputResourceLocation, list) | |
.getMessage()); | |
} else { | |
throw new IllegalStateException( | |
_loc.get("cache-marshaller-multiple-resources", | |
getId(), _inputResourceLocation, list) | |
.getMessage()); | |
} | |
} | |
if (!list.isEmpty()) | |
_inputURL = (URL) list.get(0); | |
} catch (IOException ioe) { | |
IllegalStateException ise = new IllegalStateException( | |
_loc.get("cache-marshaller-bad-url", getId(), | |
_inputResourceLocation).getMessage()); | |
ise.initCause(ioe); | |
throw ise; | |
} | |
} | |
} |