| /* |
| * 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.ArrayList; |
| import java.util.Enumeration; |
| import java.util.List; |
| |
| 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; |
| |
| @Override |
| 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 (Object value : array) { |
| configure(value); |
| } |
| } 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(); |
| } |
| } |
| |
| @Override |
| 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; |
| } |
| |
| @Override |
| public String getId() { |
| return _id; |
| } |
| |
| @Override |
| public void setId(String id) { |
| _id = id; |
| } |
| |
| @Override |
| 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; |
| } |
| |
| @Override |
| public void setConfiguration(Configuration conf) { |
| _conf = (OpenJPAConfiguration) conf; |
| _log = conf.getConfigurationLog(); |
| } |
| |
| @Override |
| public void startConfiguration() { |
| } |
| |
| @Override |
| 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.nextElement()); |
| |
| 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(), ioe); |
| throw ise; |
| } |
| } |
| } |