/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI 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.openengsb.core.persistence.internal;
import static java.lang.String.format;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import org.openengsb.core.api.persistence.PersistenceException;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Default file reader/writer implementation
*/
public class DefaultObjectPersistenceBackend implements ObjectPersistenceBackend {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultObjectPersistenceBackend.class);
private Bundle bundle;
public DefaultObjectPersistenceBackend() {
}
public DefaultObjectPersistenceBackend(Bundle bundle) {
this.bundle = bundle;
}
@Override
public void writeDatabaseObject(Object obj, File file) throws PersistenceException {
LOGGER.trace("Trying to serialize object {} to file {}", obj.getClass().getName(), file.toString());
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream(file);
out = new ObjectOutputStream(fos);
try {
out.writeObject(obj);
} catch (NotSerializableException e) {
new SerializableChecker(e).writeObject(obj);
}
} catch (IOException e) {
throw new PersistenceException(format("Could not write object %s to file %s", obj.getClass().getName(),
file.toString()), e);
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
LOGGER.debug(
format("Could not close ObjectOutputStream for object %s and file %s", obj.getClass().getName(),
file.toString()), e);
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
LOGGER.debug(
format("Could not close FileOutputStream for object %s and file %s", obj.getClass().getName(),
file.toString()), e);
}
}
}
@Override
public Object readDatabaseObject(final File file) throws PersistenceException {
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(file);
in = new ObjectInputStream(fis) {
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
LOGGER.debug(format("Trying to load class %s for file %s from current ContextClassLoader",
desc.getName(), file.toString()));
try {
return Thread.currentThread().getContextClassLoader().loadClass(desc.getName());
} catch (Throwable e) {
LOGGER.debug(format("Couldn't load class %s for file %s from current ContextClassLoader",
desc.getName(), file.toString()));
}
if (bundle != null) {
LOGGER.debug(format("Trying to load class %s for file %s from bundle %s", desc.getName(),
file.toString(), bundle.getSymbolicName()));
try {
Class<?> loadedClass = bundle.loadClass(desc.getName());
if (loadedClass != null) {
return loadedClass;
} else {
LOGGER.debug(format("Couldn't load class %s for file %s from bundle %s",
desc.getName(), file.toString(), bundle.getSymbolicName()));
}
} catch (Throwable e) {
LOGGER.debug(format("Couldn't load class %s for file %s from bundle %s", desc.getName(),
file.toString(), bundle.getSymbolicName()));
}
}
LOGGER.debug(format("Every alternative failed; try to load class %s for file %s from parent.",
desc.getName(), file.toString()));
return super.resolveClass(desc);
}
};
return in.readObject();
} catch (IOException e) {
throw new PersistenceException(format("Could not read file %s", file.toString()), e);
} catch (ClassNotFoundException e) {
throw new PersistenceException(format("Could not load required classes for file %s", file.toString()), e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
LOGGER.debug(format("Could not close ObjectInputStream for file %s", file.toString()), e);
}
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
LOGGER.debug(format("Could not close FileInputStream for file %s", file.toString()), e);
}
}
}
}