001    package org.cumulus4j.store;
002    
003    import java.util.HashMap;
004    import java.util.Map;
005    
006    import javax.jdo.FetchPlan;
007    import javax.jdo.PersistenceManager;
008    
009    import org.cumulus4j.store.model.KeyStoreRef;
010    import org.cumulus4j.store.model.KeyStoreRefDAO;
011    
012    public class KeyStoreRefManager {
013    
014            private Map<Integer, KeyStoreRef> keyStoreRefID2KeyStoreRef = new HashMap<Integer, KeyStoreRef>();
015            private Map<String, KeyStoreRef> keyStoreID2KeyStoreRef = new HashMap<String, KeyStoreRef>();
016    
017            public KeyStoreRefManager() { }
018    
019            /**
020             * Get the {@link KeyStoreRef} identified by the given <code>keyStoreRefID</code>.
021             * If no such <code>KeyStoreRef</code> exists, <code>null</code> is returned.
022             * @param persistenceManagerConnection the connection to the underlying datastore(s).
023             * @param keyStoreRefID {@link KeyStoreRef#getKeyStoreRefID() identifier} of the
024             * <code>KeyStoreRef</code> to be retrieved.
025             * @return the {@link KeyStoreRef} identified by the given <code>keyStoreRefID</code> or <code>null</code>.
026             */
027            public synchronized KeyStoreRef getKeyStoreRef(PersistenceManagerConnection persistenceManagerConnection, int keyStoreRefID)
028            {
029                    KeyStoreRef keyStoreRef = keyStoreRefID2KeyStoreRef.get(keyStoreRefID);
030                    if (keyStoreRef == null) {
031                            PersistenceManager pm = persistenceManagerConnection.getDataPM();
032                            keyStoreRef = new KeyStoreRefDAO(pm).getKeyStoreRef(keyStoreRefID);
033                            if (keyStoreRef != null) {
034                                    pm.getFetchPlan().setMaxFetchDepth(-1);
035                                    pm.getFetchPlan().setGroup(FetchPlan.ALL);
036                                    keyStoreRef = pm.detachCopy(keyStoreRef);
037                                    keyStoreRefID2KeyStoreRef.put(
038                                                    keyStoreRef.getKeyStoreRefID(), keyStoreRef
039                                    );
040                                    keyStoreID2KeyStoreRef.put(
041                                                    keyStoreRef.getKeyStoreID(), keyStoreRef
042                                    );
043                            }
044                    }
045                    return keyStoreRef;
046            }
047    
048            /**
049             * <p>
050             * Get the {@link KeyStoreRef} identified by the given properties.
051             * </p><p>
052             * If it does not yet exist in the in-memory-cache,
053             * it is looked up in the datastore. If it is found there, it is detached, cached and returned. If it does not exist in the
054             * datastore either, it is - if <code>create == true</code> - created, persisted, detached, cached and returned; if
055             * <code>create == false</code>, <code>null</code> is returned instead.
056             * </p><p>
057             * The <code>KeyStoreRef</code> instances are only held in the
058             * {@link PersistenceManagerConnection#getDataPM() data-datastore} (not in the index-datastore). This might change in the future
059             * (in case replication becomes necessary).
060             * </p>
061             *
062             * @param create whether to create a new instance, if it does not yet exist. If <code>true</code>, a new instance
063             * will be created, persisted, detached, cached and returned, if it does not yet exist. If <code>false</code>, <code>null</code>
064             * will be returned instead.
065             * @param persistenceManagerConnection the connection to the underlying datastore(s).
066             * @param keyStoreID the <code>KeyStore</code>'s ID. Must not be <code>null</code>.
067             * @return the <code>KeyStoreRef</code> (detached) matching the given properties. If <code>create == true</code>, this
068             * is never <code>null</code>. If <code>create == false</code> and there does not yet exist an appropriate
069             * <code>KeyStoreRef</code>, this is <code>null</code>.
070             */
071            protected KeyStoreRef _createOrGetKeyStoreRef(boolean create, PersistenceManagerConnection persistenceManagerConnection, String keyStoreID)
072            {
073                    KeyStoreRef keyStoreRef = keyStoreID2KeyStoreRef.get(keyStoreID);
074                    if (keyStoreRef == null) {
075                            PersistenceManager pm = persistenceManagerConnection.getDataPM();
076    
077                            if (create)
078                                    keyStoreRef = new KeyStoreRefDAO(pm).createKeyStoreRef(keyStoreID);
079                            else
080                                    keyStoreRef = new KeyStoreRefDAO(pm).getKeyStoreRef(keyStoreID);
081    
082                            if (keyStoreRef != null) {
083                                    pm.getFetchPlan().setMaxFetchDepth(-1);
084                                    pm.getFetchPlan().setGroup(FetchPlan.ALL);
085                                    keyStoreRef = pm.detachCopy(keyStoreRef);
086                                    keyStoreRefID2KeyStoreRef.put(
087                                                    keyStoreRef.getKeyStoreRefID(), keyStoreRef
088                                    );
089                                    keyStoreID2KeyStoreRef.put(
090                                                    keyStoreRef.getKeyStoreID(), keyStoreRef
091                                    );
092                            }
093                    }
094                    return keyStoreRef;
095            }
096    
097            /**
098             * <p>
099             * Get the {@link KeyStoreRef} identified by the given properties.
100             * </p><p>
101             * If there is no appropriate <code>KeyStoreRef</code> (neither in the in-memory-cache nor in the datastore),
102             * <code>null</code> is returned.
103             * </p><p>
104             * This method delegates to {@link #_createOrGetKeyStoreRef(boolean, PersistenceManagerConnection, String, String)} with
105             * <code>create == false</code>.
106             * </p>
107             *
108             * @param persistenceManagerConnection the connection to the underlying datastore(s).
109             * @param keyStoreID the <code>KeyStore</code>'s ID. Must not be <code>null</code>.
110             * @return the <code>KeyStoreRef</code> (detached) matching the given properties or <code>null</code>.
111             */
112            public synchronized KeyStoreRef getKeyStoreRef(PersistenceManagerConnection persistenceManagerConnection, String keyStoreID)
113            {
114                    return _createOrGetKeyStoreRef(false, persistenceManagerConnection, keyStoreID);
115            }
116    
117            /**
118             * <p>
119             * Get the {@link KeyStoreRef} identified by the given properties.
120             * </p><p>
121             * If there is no appropriate <code>KeyStoreRef</code> (neither in the in-memory-cache nor in the datastore),
122             * it is created and persisted.
123             * </p><p>
124             * This method delegates to {@link #_createOrGetKeyStoreRef(boolean, PersistenceManagerConnection, String, String)} with
125             * <code>create == true</code>.
126             * </p>
127             *
128             * @param persistenceManagerConnection the connection to the underlying datastore(s).
129             * @param keyStoreID the <code>KeyStore</code>'s ID. Must not be <code>null</code>.
130             * @return the <code>KeyStoreRef</code> (detached) matching the given properties; never <code>null</code>.
131             */
132            public synchronized KeyStoreRef createKeyStoreRef(PersistenceManagerConnection persistenceManagerConnection, String keyStoreID)
133            {
134                    return _createOrGetKeyStoreRef(true, persistenceManagerConnection, keyStoreID);
135            }
136    }