001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.store.jdbc;
018    
019    import java.io.ByteArrayInputStream;
020    import java.io.ByteArrayOutputStream;
021    import java.io.IOException;
022    import java.io.ObjectInputStream;
023    import java.io.ObjectOutputStream;
024    import java.sql.Connection;
025    
026    import org.apache.commons.logging.Log;
027    import org.apache.commons.logging.LogFactory;
028    import org.apache.servicemix.store.Store;
029    
030    public class JdbcStore implements Store {
031    
032        private static final Log LOG = LogFactory.getLog(JdbcStore.class);
033    
034        private JdbcStoreFactory factory;
035        private String name;
036        
037        public JdbcStore(JdbcStoreFactory factory, String name) {
038            this.factory = factory;
039            this.name = name;
040        }
041    
042        public boolean hasFeature(String feature) {
043            return PERSISTENT.equals(feature) 
044                || (CLUSTERED.equals(feature) && factory.isClustered())
045                || (TRANSACTIONAL.equals(feature) && factory.isTransactional());
046        }
047    
048        public void store(String id, Object data) throws IOException {
049            LOG.debug("Storing object with id: " + id);
050            Connection connection = null;
051            try {
052                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
053                ObjectOutputStream out = new ObjectOutputStream(buffer);
054                out.writeObject(data);
055                out.close();
056                connection = factory.getDataSource().getConnection();
057                factory.getAdapter().doStoreData(connection, name + ":" + id, buffer.toByteArray());
058            } catch (Exception e) {
059                throw (IOException) new IOException("Error storing object").initCause(e);
060            } finally {
061                close(connection);
062            }
063        }
064    
065        public String store(Object data) throws IOException {
066            String id = factory.getIdGenerator().generateId();
067            store(id, data);
068            return id;
069        }
070    
071        public Object load(String id) throws IOException {
072            LOG.debug("Loading object with id: " + id);
073            Connection connection = null;
074            try {
075                connection = factory.getDataSource().getConnection();
076                byte[] data = factory.getAdapter().doLoadData(connection, name + ":" + id);
077                Object result = null;
078                if (data != null) {
079                    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
080                    result = ois.readObject();
081                    factory.getAdapter().doRemoveData(connection, name + ":" + id);
082                }
083                return result;
084            } catch (Exception e) {
085                throw (IOException) new IOException("Error storing object").initCause(e);
086            } finally {
087                close(connection);
088            }
089        }
090    
091        protected void close(Connection connection) throws IOException {
092            if (connection != null) {
093                try {
094                    connection.close();
095                } catch (Exception e) {
096                    throw (IOException) new IOException("Error closing connection").initCause(e);
097                }
098            }
099        }
100    
101    }