001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.event;
020:
021: import java.io.Externalizable;
022: import java.io.IOException;
023: import java.io.ObjectInput;
024: import java.io.ObjectOutput;
025: import java.util.Collection;
026: import java.util.Collections;
027:
028: import org.apache.openjpa.lib.util.Localizer;
029: import org.apache.openjpa.util.UserException;
030:
031: /**
032: * Event type to hold the IDs of additions, updates, and
033: * deletes. This event type is also fully serializable for remote communication.
034: *
035: * @since 0.3.0
036: * @author Patrick Linskey
037: * @author Abe White
038: */
039: public class RemoteCommitEvent implements Externalizable {
040:
041: /**
042: * Names of added classes, updated and deleted Object IDs.
043: */
044: public static final int PAYLOAD_OIDS = 0;
045:
046: /**
047: * Names of added classes, added, updated and deleted Object IDs.
048: */
049: public static final int PAYLOAD_OIDS_WITH_ADDS = 1;
050:
051: /**
052: * Names of added, updated, and deleted classes only.
053: */
054: public static final int PAYLOAD_EXTENTS = 2;
055:
056: /**
057: * The local {@link BrokerFactory} detected that local data is out of date
058: * with the data store. Stale object IDs will be in t he updated set,
059: * although it is possible that records were actually deleted, rather than
060: * updated.
061: *
062: * @since 1.0.0
063: */
064: public static final int PAYLOAD_LOCAL_STALE_DETECTION = 3;
065:
066: private static final Localizer s_loc = Localizer
067: .forPackage(RemoteCommitEvent.class);
068:
069: private int _payload = PAYLOAD_OIDS;
070: private Collection _addIds = null;
071: private Collection _addClasses = null;
072: private Collection _updates = null;
073: private Collection _deletes = null;
074:
075: /**
076: * Constructor used during externalization.
077: */
078: public RemoteCommitEvent() {
079: }
080:
081: /**
082: * Constructor. All collections will be proxied with unmodifiable views.
083: *
084: * @param payloadType PAYLOAD constant for type of data in this event
085: * @param addIds set of object IDs for added instances, or null
086: * @param addClasses set of class names for added instances
087: * @param updates set of class names or object IDs for updated instances
088: * @param deletes set of class names or object IDs for deleted instances
089: */
090: public RemoteCommitEvent(int payloadType, Collection addIds,
091: Collection addClasses, Collection updates,
092: Collection deletes) {
093: _payload = payloadType;
094: if (addIds != null)
095: _addIds = Collections.unmodifiableCollection(addIds);
096: if (addClasses != null)
097: _addClasses = Collections
098: .unmodifiableCollection(addClasses);
099: if (updates != null)
100: _updates = Collections.unmodifiableCollection(updates);
101: if (deletes != null)
102: _deletes = Collections.unmodifiableCollection(deletes);
103: }
104:
105: /**
106: * The event PAYLOAD constant.
107: */
108: public int getPayloadType() {
109: return _payload;
110: }
111:
112: /**
113: * When the event type is PAYLOAD_OIDS_WITH_ADDS, return the set of
114: * object IDs for added objects. This will only be callable when the
115: * backward compatability property transmitAddObjectIds is true.
116: */
117: public Collection getPersistedObjectIds() {
118: if (_payload != PAYLOAD_OIDS_WITH_ADDS) {
119: if (_payload == PAYLOAD_OIDS)
120: throw new UserException(s_loc.get("no-added-oids"));
121: throw new UserException(s_loc.get("extent-only-event"));
122: }
123: return (_addIds == null) ? Collections.EMPTY_LIST : _addIds;
124: }
125:
126: /**
127: * When the event type is not PAYLOAD_EXTENTS, return the set of
128: * object IDs for updated objects. When the event type is
129: * PAYLOAD_LOCAL_STALE_DETECTION, items in this list may actually have
130: * been deleted from the database.
131: */
132: public Collection getUpdatedObjectIds() {
133: if (_payload == PAYLOAD_EXTENTS)
134: throw new UserException(s_loc.get("extent-only-event"));
135: return (_updates == null) ? Collections.EMPTY_LIST : _updates;
136: }
137:
138: /**
139: * When the event type is not PAYLOAD_EXTENTS, return the set of
140: * object IDs for deleted objects.
141: */
142: public Collection getDeletedObjectIds() {
143: if (_payload == PAYLOAD_EXTENTS)
144: throw new UserException(s_loc.get("extent-only-event"));
145: return (_deletes == null) ? Collections.EMPTY_LIST : _deletes;
146: }
147:
148: /**
149: * For all event types, return the set of class names for
150: * the classes of inserted objects.
151: */
152: public Collection getPersistedTypeNames() {
153: return (_addClasses == null) ? Collections.EMPTY_LIST
154: : _addClasses;
155: }
156:
157: /**
158: * When the event type is PAYLOAD_EXTENTS, return the set of class
159: * names for the classes of updated objects.
160: */
161: public Collection getUpdatedTypeNames() {
162: if (_payload != PAYLOAD_EXTENTS)
163: throw new UserException(s_loc.get("nonextent-event"));
164: return (_updates == null) ? Collections.EMPTY_LIST : _updates;
165: }
166:
167: /**
168: * When the event type is PAYLOAD_EXTENTS, return the set of class
169: * names for the classes of deleted objects.
170: */
171: public Collection getDeletedTypeNames() {
172: if (_payload != PAYLOAD_EXTENTS)
173: throw new UserException(s_loc.get("nonextent-event"));
174: return (_deletes == null) ? Collections.EMPTY_LIST : _deletes;
175: }
176:
177: public void writeExternal(ObjectOutput out) throws IOException {
178: out.writeInt(_payload);
179: out.writeObject(_addClasses);
180: if (_payload == PAYLOAD_OIDS_WITH_ADDS)
181: out.writeObject(_addIds);
182: out.writeObject(_updates);
183: out.writeObject(_deletes);
184: }
185:
186: public void readExternal(ObjectInput in) throws IOException {
187: try {
188: _payload = in.readInt();
189: _addClasses = (Collection) in.readObject();
190: if (_payload == PAYLOAD_OIDS_WITH_ADDS)
191: _addIds = (Collection) in.readObject();
192: _updates = (Collection) in.readObject();
193: _deletes = (Collection) in.readObject();
194: } catch (ClassNotFoundException cnfe) {
195: // ### do something
196: }
197: }
198: }
|