00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00019 package cast.architecture;
00020
00021 import java.util.Map;
00022
00023 import org.apache.log4j.Level;
00024
00025 import Ice.Current;
00026 import Ice.Object;
00027 import Ice.ObjectImpl;
00028 import cast.AlreadyExistsOnWMException;
00029 import cast.ConsistencyException;
00030 import cast.DoesNotExistOnWMException;
00031 import cast.PermissionException;
00032 import cast.UnknownSubarchitectureException;
00033 import cast.cdl.COMPONENTNUMBERKEY;
00034 import cast.cdl.WorkingMemoryAddress;
00035 import cast.core.CASTUtils;
00036 import cast.core.logging.ComponentLogger;
00037 import cast.interfaces.WorkingMemoryPrx;
00038 import cast.interfaces.WorkingMemoryPrxHelper;
00039
00046 public abstract class WorkingMemoryWriterComponent extends
00047 WorkingMemoryAttachedComponent {
00048
00049 protected int m_dataCount;
00050
00051 private int m_componentNumber;
00052
00053 private String m_componentNumberString;
00054
00055 private ComponentLogger m_loggerForAdditions;
00056 private ComponentLogger m_loggerForOverwrites;
00057 private ComponentLogger m_loggerForDeletes;
00058
00063 private WorkingMemoryPrx m_workingMemoryForWrite;
00064
00068 public WorkingMemoryWriterComponent() {
00069 m_dataCount = 0;
00070 m_componentNumber = -1;
00071 }
00072
00073 @Override
00074 protected void startInternal() {
00075 super.startInternal();
00076 m_loggerForAdditions = getLogger(".wm.rw.add");
00077 m_loggerForOverwrites = getLogger(".wm.rw.ovr");
00078 m_loggerForDeletes = getLogger(".wm.rw.del");
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 @Override
00089 public void configureInternal(Map<String, String> _config) {
00090 super.configureInternal(_config);
00091 String componentNumber = _config.get(COMPONENTNUMBERKEY.value);
00092 assert (componentNumber != null);
00093 m_componentNumber = Integer.parseInt(componentNumber);
00094 m_componentNumberString = stringify(m_componentNumber);
00095 }
00096
00110 public <T extends ObjectImpl> void addToWorkingMemory(String _id, T _data)
00111 throws AlreadyExistsOnWMException {
00112 try {
00113 addToWorkingMemory(_id, getSubarchitectureID(), _data);
00114 } catch (UnknownSubarchitectureException e) {
00115 throw new RuntimeException(
00116 "Shouldn't happen on own subarchitecture", e);
00117 }
00118 }
00119
00134 public <T extends Object> void addToWorkingMemory(
00135 WorkingMemoryAddress _wma, T _data)
00136 throws AlreadyExistsOnWMException, DoesNotExistOnWMException,
00137 UnknownSubarchitectureException {
00138 addToWorkingMemory(_wma.id, _wma.subarchitecture, _data);
00139 }
00140
00155 public <T extends Ice.Object> void addToWorkingMemory(String _id,
00156 String _subarch, T _data) throws AlreadyExistsOnWMException,
00157 UnknownSubarchitectureException {
00158
00159 assert _id.length() > 0 : "id must not be empty";
00160 assert _subarch.length() > 0 : "subarchitecture id must not be empty";
00161
00162
00163
00164 String type = CASTUtils.typeName(_data);
00165
00166
00167
00168
00169 int versionWhichWillEndUpOnWM = 0;
00170
00171
00172 if (!isVersioned(_id)) {
00173 debug("is not versioned: " + _id);
00174 startVersioning(_id);
00175 }
00176
00177 else {
00178 debug("re-adding to working memory with id " + _id);
00179
00180 try {
00181 versionWhichWillEndUpOnWM = getVersionNumber(_id, _subarch) + 1;
00182 storeVersionNumber(_id, versionWhichWillEndUpOnWM);
00183 } catch (DoesNotExistOnWMException e) {
00184 throw new RuntimeException(
00185 "Error in versioning for data re-added to working memory",
00186 e);
00187 }
00188 }
00189 m_workingMemoryForWrite.addToWorkingMemory(_id, _subarch, type,
00190 getComponentID(), _data);
00191
00192 logAdd(_id, _subarch, type, versionWhichWillEndUpOnWM);
00193 }
00194
00204 private final void logAdd(String _id, String _subarch, String _type,
00205 int _version) {
00206
00207 if (m_loggerForAdditions.isTraceEnabled()) {
00208 m_loggerForAdditions.trace(CASTUtils.concatenate("add,",
00209 CASTUtils.toString(getCASTTime()), ",", _id, ",", _subarch,
00210 ",", _type, ",", _version), getLogAdditions());
00211 }
00212 }
00213
00222 private final void logOverwrite(String _id, String _subarch, String _type,
00223 int _version) {
00224
00225 if (m_loggerForOverwrites.isTraceEnabled()) {
00226 m_loggerForOverwrites.trace(CASTUtils.concatenate("ovr,",
00227 CASTUtils.toString(getCASTTime()), ",", _id, ",", _subarch,
00228 ",", _type, ",", _version), getLogAdditions());
00229 }
00230 }
00231
00240 private final void logDelete(String _id, String _subarch) {
00241
00242 if (m_loggerForDeletes.isTraceEnabled()) {
00243 m_loggerForDeletes.trace(
00244 CASTUtils.concatenate("del,",
00245 CASTUtils.toString(getCASTTime()), ",", _id, ",",
00246 _subarch), getLogAdditions());
00247 }
00248 }
00249
00259 public void deleteFromWorkingMemory(String _id)
00260 throws DoesNotExistOnWMException, PermissionException {
00261 try {
00262 deleteFromWorkingMemory(_id, getSubarchitectureID());
00263 } catch (UnknownSubarchitectureException e) {
00264 throw new RuntimeException(
00265 "Shouldn't happen on own subarchitecture", e);
00266 }
00267 }
00268
00279 public void deleteFromWorkingMemory(WorkingMemoryAddress _wma)
00280 throws DoesNotExistOnWMException, PermissionException,
00281 UnknownSubarchitectureException {
00282 deleteFromWorkingMemory(_wma.id, _wma.subarchitecture);
00283 }
00284
00299 public void deleteFromWorkingMemory(String _id, String _subarch)
00300 throws DoesNotExistOnWMException, PermissionException,
00301 UnknownSubarchitectureException {
00302
00303 assert _id.length() > 0 : "id must not be empty";
00304 assert _subarch.length() > 0 : "subarchitecture id must not be empty";
00305
00306
00307
00308
00309
00310 if (!existsOnWorkingMemory(_id, _subarch)) {
00311 throw new cast.DoesNotExistOnWMException(
00312 "Entry does not exist for deleting. Was looking for id "
00313 + _id + " in sa " + _subarch,
00314 new WorkingMemoryAddress(_subarch, _id));
00315 }
00316
00317
00318 if (!holdsDeleteLock(_id, _subarch)) {
00319
00320 if (!isDeletable(_id, _subarch)) {
00321 throw new cast.PermissionException(
00322 "Delete not allowed on locked item: " + _id + ":"
00323 + _subarch, new WorkingMemoryAddress(_subarch,
00324 _id));
00325 }
00326 }
00327
00328
00329
00330
00331 m_workingMemory
00332 .deleteFromWorkingMemory(_id, _subarch, getComponentID());
00333
00334 logDelete(_id, _subarch);
00335 }
00336
00337 private static final char[] id_table = { '0', '1', '2', '3', '4', '5', '6',
00338 '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
00339 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
00340 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
00341 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
00342 'x', 'y', 'z' };
00343
00344 private static final int ID_TABLE_SIZE = 62;
00345
00349 private final String stringify(int _n) {
00350 if (_n == 0)
00351 return "0";
00352
00353 String ret = new String();
00354
00355
00356 while (_n != 0) {
00357 int m = _n % ID_TABLE_SIZE;
00358 ret += id_table[m];
00359 _n -= m;
00360 _n /= ID_TABLE_SIZE;
00361 }
00362 return ret;
00363 }
00364
00365 public final String newDataID() {
00366
00367 StringBuffer sb = new StringBuffer(stringify(m_dataCount++));
00368 sb.append(":");
00369 if (m_logger.getLevel() == Level.TRACE) {
00370 sb.append(getComponentID());
00371 sb.append(":data");
00372 } else {
00373 sb.append(m_componentNumberString);
00374 }
00375 return sb.toString();
00376
00377 }
00378
00395 public <T extends Object> void overwriteWorkingMemory(String _id, T _data)
00396 throws DoesNotExistOnWMException, ConsistencyException,
00397 PermissionException {
00398
00399 try {
00400 overwriteWorkingMemory(_id, getSubarchitectureID(), _data);
00401 } catch (UnknownSubarchitectureException e) {
00402 throw new RuntimeException(
00403 "Shouldn't happen on own subarchitecture", e);
00404 }
00405 }
00406
00424 public <T extends Object> void overwriteWorkingMemory(
00425 WorkingMemoryAddress _wma, T _data)
00426 throws DoesNotExistOnWMException, ConsistencyException,
00427 PermissionException, UnknownSubarchitectureException {
00428 overwriteWorkingMemory(_wma.id, _wma.subarchitecture, _data);
00429 }
00430
00449 public <T extends Object> void overwriteWorkingMemory(String _id,
00450 String _subarch, T _data) throws DoesNotExistOnWMException,
00451 PermissionException, ConsistencyException,
00452 UnknownSubarchitectureException {
00453
00454 assert _id.length() > 0 : "id must not be empty";
00455 assert _subarch.length() > 0 : "subarchitecture id must not be empty";
00456
00457
00458
00459
00460 if (!existsOnWorkingMemory(_id, _subarch)) {
00461 throw new DoesNotExistOnWMException(
00462 "Entry does not exist for overwriting. Was looking for id "
00463 + _id + " in sa " + _subarch,
00464 new WorkingMemoryAddress(_subarch, _id));
00465 }
00466
00467
00468 if (!holdsOverwriteLock(_id, _subarch)) {
00469
00470 if (!isOverwritable(_id, _subarch)) {
00471 throw new PermissionException(
00472 "Overwrite not allowed on locked item: " + _id + ":"
00473 + _subarch, new WorkingMemoryAddress(_subarch,
00474 _id));
00475 }
00476
00477
00478 checkConsistency(_id, _subarch);
00479 } else {
00480
00481
00482 if (needsConsistencyCheck(_id, _subarch)) {
00483 debug("one-time consistency check for locked item: " + _id
00484 + ":" + _subarch);
00485
00486
00487 checkConsistency(_id, _subarch);
00488 consistencyChecked(_id, _subarch);
00489
00490 } else {
00491 debug("skipping consistency check for locked item: " + _id
00492 + ":" + _subarch);
00493 }
00494 }
00495
00496 String type = CASTUtils.typeName(_data);
00497
00498
00499
00500 m_workingMemoryForWrite.overwriteWorkingMemory(_id, _subarch, type,
00501 getComponentID(), _data);
00502
00503
00504
00505 increaseStoredVersion(_id);
00506
00507 logOverwrite(_id, _subarch, type, getStoredVersionNumber(_id));
00508 }
00509
00513 @Override
00514 public void setWorkingMemory(WorkingMemoryPrx _wm, Current __current) {
00515 super.setWorkingMemory(_wm, __current);
00516
00517
00518 if (m_workingMemory.ice_isCollocationOptimized()) {
00519
00520
00521 m_workingMemoryForWrite = WorkingMemoryPrxHelper
00522 .uncheckedCast(m_workingMemory
00523 .ice_collocationOptimized(false));
00524 } else {
00525 m_workingMemoryForWrite = m_workingMemory;
00526 }
00527 }
00528
00537 protected boolean resetWriteCollocationOptimisation() {
00538 m_workingMemoryForWrite = m_workingMemory;
00539 return m_workingMemoryForWrite.ice_isCollocationOptimized();
00540 }
00541
00548 protected void turnOffWriteCollocationOptimisation() {
00549
00550 if (m_workingMemoryForWrite.ice_isCollocationOptimized()) {
00551 m_workingMemoryForWrite = WorkingMemoryPrxHelper
00552 .uncheckedCast(m_workingMemory
00553 .ice_collocationOptimized(false));
00554 }
00555 }
00556
00557 }