KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > persist > impl > PersistKeyCreator


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: PersistKeyCreator.java,v 1.16 2006/10/30 21:14:32 bostic Exp $
7  */

8
9 package com.sleepycat.persist.impl;
10
11 import java.util.Collection JavaDoc;
12 import java.util.Set JavaDoc;
13
14 import com.sleepycat.bind.tuple.TupleBase;
15 import com.sleepycat.je.DatabaseEntry;
16 import com.sleepycat.je.DatabaseException;
17 import com.sleepycat.je.ForeignMultiKeyNullifier;
18 import com.sleepycat.je.SecondaryDatabase;
19 import com.sleepycat.je.SecondaryKeyCreator;
20 import com.sleepycat.je.SecondaryMultiKeyCreator;
21 import com.sleepycat.persist.model.EntityMetadata;
22 import com.sleepycat.persist.model.Relationship;
23 import com.sleepycat.persist.model.SecondaryKeyMetadata;
24 import com.sleepycat.persist.raw.RawObject;
25
26 /**
27  * A persistence secondary key creator/nullifier. This class always uses
28  * rawAccess=true to avoid depending on the presence of the proxy class.
29  *
30  * @author Mark Hayes
31  */

32 public class PersistKeyCreator implements SecondaryKeyCreator,
33                                           SecondaryMultiKeyCreator,
34                                           ForeignMultiKeyNullifier {
35
36     static boolean isManyType(Class JavaDoc cls) {
37         return cls.isArray() || Collection JavaDoc.class.isAssignableFrom(cls);
38     }
39
40     private Catalog catalog;
41     private int priKeyFormatId;
42     private String JavaDoc keyName;
43     private Format keyFormat;
44     private boolean toMany;
45
46     /**
47      * Creates a key creator/nullifier for a given entity class and key name.
48      */

49     public PersistKeyCreator(Catalog catalog,
50                              EntityMetadata entityMeta,
51                              String JavaDoc keyClassName,
52                              SecondaryKeyMetadata secKeyMeta) {
53         this.catalog = catalog;
54         Format priKeyFormat =
55             catalog.getFormat(entityMeta.getPrimaryKey().getClassName());
56         priKeyFormatId = priKeyFormat.getId();
57         keyName = secKeyMeta.getKeyName();
58         keyFormat = catalog.getFormat(keyClassName);
59         if (keyFormat == null) {
60             throw new IllegalArgumentException JavaDoc
61                 ("Not a key class: " + keyClassName);
62         }
63         if (keyFormat.isPrimitive()) {
64             throw new IllegalArgumentException JavaDoc
65                 ("Use a primitive wrapper class instead of class: " +
66                  keyFormat.getClassName());
67         }
68         Relationship rel = secKeyMeta.getRelationship();
69         toMany = (rel == Relationship.ONE_TO_MANY ||
70                   rel == Relationship.MANY_TO_MANY);
71     }
72
73     public boolean createSecondaryKey(SecondaryDatabase secondary,
74                       DatabaseEntry key,
75                       DatabaseEntry data,
76                       DatabaseEntry result)
77     throws DatabaseException {
78
79         if (toMany) {
80             throw new IllegalStateException JavaDoc();
81         }
82         KeyLocation loc = moveToKey(key, data);
83         if (loc != null) {
84             RecordOutput output = new RecordOutput
85                 (catalog, true /*rawAccess*/);
86             loc.format.copySecKey(loc.input, output);
87             TupleBase.outputToEntry(output, result);
88             return true;
89         } else {
90             /* Key field is not present or null. */
91             return false;
92         }
93     }
94
95     public void createSecondaryKeys(SecondaryDatabase secondary,
96                     DatabaseEntry key,
97                     DatabaseEntry data,
98                     Set JavaDoc results)
99     throws DatabaseException {
100
101         if (!toMany) {
102             throw new IllegalStateException JavaDoc();
103         }
104         KeyLocation loc = moveToKey(key, data);
105         if (loc != null) {
106             loc.format.copySecMultiKey(loc.input, keyFormat, results);
107         }
108         /* Else key field is not present or null. */
109     }
110
111     public boolean nullifyForeignKey(SecondaryDatabase secondary,
112                                      DatabaseEntry key,
113                                      DatabaseEntry data,
114                                      DatabaseEntry secKey)
115     throws DatabaseException {
116
117         /* Deserialize the entity and get its current class format. */
118         RawObject entity = (RawObject) PersistEntityBinding.readEntity
119             (catalog, key, data, true /*rawAccess*/);
120         Format entityFormat = (Format) entity.getType();
121
122         /*
123          * Set the key to null. For a TO_MANY key, pass the key object to be
124          * removed from the array/collection.
125          */

126         Object JavaDoc secKeyObject = null;
127         if (toMany) {
128             secKeyObject = PersistKeyBinding.readKey
129                 (keyFormat, catalog, secKey.getData(), secKey.getOffset(),
130                  secKey.getSize(), true /*rawAccess*/);
131         }
132         if (entityFormat.nullifySecKey
133             (catalog, entity, keyName, secKeyObject)) {
134
135             /*
136              * Using the current format for the entity, serialize the modified
137              * entity back to the data entry.
138              */

139             PersistEntityBinding.writeEntity
140                 (entityFormat, catalog, entity, data, true /*rawAccess*/);
141             return true;
142         } else {
143             /* Key field is not present or null. */
144             return false;
145         }
146     }
147
148     /**
149      * Returns the location from which the secondary key field can be copied.
150      */

151     private KeyLocation moveToKey(DatabaseEntry priKey, DatabaseEntry data) {
152
153         RecordInput input = new RecordInput
154             (catalog, true /*rawAccess*/, priKey, priKeyFormatId,
155              data.getData(), data.getOffset(), data.getSize());
156         int formatId = input.readPackedInt();
157         Format entityFormat = catalog.getFormat(formatId);
158         Format fieldFormat = entityFormat.skipToSecKey(input, keyName);
159         if (fieldFormat != null) {
160             /* Returns null if key field is null. */
161             return input.getKeyLocation(fieldFormat);
162         } else {
163             /* Key field is not present in this class. */
164             return null;
165         }
166     }
167 }
168
Popular Tags