001: /**
002: * Copyright (C) 2001-2005 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.genclass;
018:
019: import java.util.ArrayList;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Map;
023: import java.util.Collection;
024:
025: import org.objectweb.jorm.api.PExceptionIO;
026: import org.objectweb.jorm.api.PGenClassAccessor;
027: import org.objectweb.jorm.api.PIndexedElem;
028: import org.objectweb.jorm.util.api.Loggable;
029: import org.objectweb.speedo.api.Debug;
030: import org.objectweb.speedo.genclass.api.SpeedoGenClassCoherence;
031: import org.objectweb.speedo.genclass.api.SpeedoGenClassPO;
032: import org.objectweb.speedo.mim.api.StateItf;
033: import org.objectweb.speedo.mim.lib.AbstractStateImpl;
034: import org.objectweb.speedo.pm.api.POManagerItf;
035: import org.objectweb.util.monolog.api.BasicLevel;
036: import org.objectweb.util.monolog.api.Logger;
037:
038: /**
039: * This class represents an accessor of a genclass structure. This accessor is
040: * used in case of the generic class is persistent.
041: *
042: * @author S.Chassande-Barrioz
043: */
044: public abstract class GenClassAccessor extends AbstractStateImpl
045: implements PGenClassAccessor, SpeedoGenClassCoherence {
046:
047: /**
048: * The PersistentObjectItf attached to this state representation.
049: */
050: public SpeedoGenClassPO gcpo;
051:
052: /**
053: * Indicates if this accessor support the dela mode
054: */
055: public boolean supportDelta = true;
056:
057: /**
058: * A temporary variable which is used to search an element into the
059: * "elements" list.
060: */
061: protected GenClassElement tmpelem = null;
062:
063: protected transient Logger logger;
064:
065: /**
066: * The ArrayList used to store the indexed elements of the genclass. Then
067: * this list contains also the deleted elements.
068: */
069: public List elements = null;
070:
071: public List deltaForMerge = null;
072:
073: public GenClassAccessor(SpeedoGenClassPO thepo) {
074: super (thepo);
075: elements = new ArrayList();
076: this .gcpo = thepo;
077: this .tmpelem = (GenClassElement) createPIndexedElem();
078: }
079:
080: public abstract void loadFieldsFromAccessor(StateItf sa);
081:
082: public abstract PIndexedElem createPIndexedElem(GenClassAccessor gca);
083:
084: public abstract void setElements(Object o);
085:
086: public Logger getLogger() {
087: if (logger == null) {
088: logger = ((Loggable) gcpo).getLogger();
089: }
090: return logger;
091: }
092:
093: /**
094: * When the gen class is flushed to the data support (parameter = true),
095: * the internal structure is clean: - really remove the deleted element -
096: * mark the genclass as supporting the delta
097: */
098: public void setFlushed(boolean val) {
099: super .setFlushed(val);
100: if (val == true) {
101: supportDelta = true;
102: Iterator it = elements.iterator();
103: while (it.hasNext()) {
104: GenClassElement gce = (GenClassElement) it.next();
105: if (gce.getElemStatus() == PIndexedElem.ELEM_DELETED) {
106: //Remove the deleted element
107: it.remove();
108: }
109: }
110: }
111: }
112:
113: /**
114: * At the end of the working set, the writing mode is initialized
115: * (deltaSupported), and the reference to the persistent are unswilled
116: */
117: public void workingSetClosed() {
118: if (Debug.ON) {
119: ((Loggable) gcpo).getLogger().log(BasicLevel.DEBUG,
120: "workingSetClosed()");
121: }
122: supportDelta = true;
123: for (Iterator it = elements.iterator(); it.hasNext();) {
124: GenClassElement gce = (GenClassElement) it.next();
125: if (gce.getElemStatus() == PIndexedElem.ELEM_DELETED) {
126: //Remove the deleted element
127: it.remove();
128: }
129: }
130: }
131:
132: public void unSwizzle() {
133: for (Iterator it = elements.iterator(); it.hasNext();) {
134: GenClassElement gce = (GenClassElement) it.next();
135: gce.unSwizzle();
136: }
137: }
138:
139: public org.objectweb.perseus.persistence.api.State merge(
140: org.objectweb.perseus.persistence.api.State oldState) {
141: if (deltaForMerge == null || !isToMerge) {
142: return super .merge(oldState);
143: }
144: GenClassAccessor gca = (GenClassAccessor) oldState;
145: for (int i = 0; i < deltaForMerge.size(); i++) {
146: GenClassElement gce = (GenClassElement) deltaForMerge
147: .get(i);
148: switch (gce.getStatusForMerge()) {
149: case PIndexedElem.ELEM_CREATED:
150: gca.elements.add(gce);
151: break;
152: case PIndexedElem.ELEM_DELETED:
153: int idx = gca.elements.indexOf(gce);
154: if (idx == -1) {
155: logger
156: .log(
157: BasicLevel.WARN,
158: "Deleted GenClass element '"
159: + gce
160: + "' not found during merging among "
161: + gca.elements);
162: } else {
163: gca.elements.remove(idx);
164: }
165: break;
166: case PIndexedElem.ELEM_MODIFIED:
167: idx = gca.elements.indexOf(gce);
168: if (idx == -1) {
169: logger.log(BasicLevel.WARN,
170: "Modified GenClass element not found during merging: "
171: + gce);
172: } else {
173: gca.elements.set(idx, gce);
174: }
175: break;
176: }
177: gce.cleanStatusForMerge();
178: }
179: deltaForMerge = null;
180: return super .merge(oldState);
181: }
182:
183: public void makeToMerge(Object thinLock) {
184: if (!isToMerge) {
185: for (int i = 0; i < elements.size(); i++) {
186: elements.set(i, ((GenClassElement) elements.get(i))
187: .cloneGCE());
188: }
189: }
190: super .makeToMerge(thinLock);
191: }
192:
193: public void loadFields(POManagerItf pm, long[] fields) {
194: }
195:
196: public abstract void deletePersistent(POManagerItf pm);
197:
198: public abstract void makePersistent(POManagerItf pm);
199:
200: public abstract void makePersistentOnAttach(POManagerItf pm, Map map);
201:
202: public abstract void detachCopy(POManagerItf pm, Map map,
203: StateItf fieldsClone, Collection fgHints);
204:
205: public abstract void attachCopy(POManagerItf pm, Map map,
206: StateItf fieldsClone);
207:
208: public abstract void refresh(POManagerItf pm, Map map,
209: Collection fgHints);
210:
211: public abstract void retrieve(POManagerItf pm, Map map,
212: Collection fgHints);
213:
214: // IMPLEMENTATION OF THE SpeedoGenClassCoherence INTERFACE //
215: //---------------------------------------------------------//
216:
217: public abstract boolean speedoAdd(Object elemToAdd, Object hints);
218:
219: public abstract boolean speedoRemove(Object elemToRemove,
220: Object hints);
221:
222: // IMPLEMENTATION OF THE PGenClassAccessor INTERFACE //
223: //---------------------------------------------------//
224:
225: public PIndexedElem createPIndexedElem() {
226: return createPIndexedElem(this );
227: }
228:
229: public Object getMemoryInstance() {
230: return gcpo;
231: }
232:
233: public void paAdd(PIndexedElem elem, Object conn)
234: throws PExceptionIO {
235: // the elem is read from the DS, set it to unmodified.
236: ((GenClassElement) elem)
237: .setStatus(PIndexedElem.ELEM_UNMODIFIED);
238: elements.add(elem);
239: }
240:
241: public int paGetNbElem() {
242: return elements.size();
243: }
244:
245: public Iterator paIterator() {
246: return elements.iterator();
247: }
248:
249: public boolean paDeltaSupported() {
250: return supportDelta;
251: }
252:
253: public void paSetNbElem(int nbelem) {
254: elements = (nbelem < 0 ? new ArrayList()
255: : new ArrayList(nbelem));
256: }
257:
258: }
|