00001
00004 package cast.architecture;
00005
00006 import java.util.Hashtable;
00007 import java.util.Map;
00008
00009 import org.apache.log4j.Logger;
00010
00011 import Ice.Current;
00012 import cast.ConsistencyException;
00013 import cast.DoesNotExistOnWMException;
00014 import cast.UnknownSubarchitectureException;
00015 import cast.WMException;
00016 import cast.cdl.WorkingMemoryAddress;
00017 import cast.cdl.WorkingMemoryPermissions;
00018 import cast.core.CASTComponentPermissionsMap;
00019 import cast.core.CASTUtils;
00020 import cast.core.SubarchitectureComponent;
00021 import cast.interfaces.WorkingMemoryPrx;
00022 import cast.interfaces.WorkingMemoryPrxHelper;
00023 import cast.interfaces._WorkingMemoryAttachedComponentOperations;
00024
00033 public abstract class WorkingMemoryAttachedComponent extends
00034 SubarchitectureComponent implements
00035 _WorkingMemoryAttachedComponentOperations {
00036
00037 protected WorkingMemoryPrx m_workingMemory;
00038
00039 public void setWorkingMemory(WorkingMemoryPrx _wm, Current __current) {
00040 assert (_wm != null);
00041 m_workingMemory = _wm;
00042 }
00043
00044 private final Hashtable<String, Integer> m_versionNumbers;
00045
00046 private CASTComponentPermissionsMap m_permissions;
00047
00051 public WorkingMemoryAttachedComponent() {
00052 m_versionNumbers = new Hashtable<String, Integer>();
00053 }
00054
00055
00056 @Override
00057 protected void configureInternal(Map<String, String> _config) {
00058 super.configureInternal(_config);
00059 m_permissions = new CASTComponentPermissionsMap(getSubarchitectureID());
00060 }
00061
00070 public final boolean existsOnWorkingMemory(String _id) {
00071
00072 try {
00073 return existsOnWorkingMemory(_id, getSubarchitectureID());
00074 } catch (UnknownSubarchitectureException e) {
00075 throw new RuntimeException(
00076 "Shouldn't happen on own subarchitecture", e);
00077 }
00078 }
00079
00091 public final boolean existsOnWorkingMemory(String _id, String _subarch)
00092 throws UnknownSubarchitectureException {
00093
00094 assert _id.length() > 0 : "id must not be empty";
00095 assert _subarch.length() > 0 : "subarchitecture id must not be empty";
00096 assert m_workingMemory != null;
00097
00098 return m_workingMemory.exists(_id, _subarch);
00099
00100 }
00101
00111 public final boolean existsOnWorkingMemory(WorkingMemoryAddress _wma)
00112 throws UnknownSubarchitectureException {
00113 return existsOnWorkingMemory(_wma.id, _wma.subarchitecture);
00114 }
00115
00131 public final int getVersionNumber(String _id)
00132 throws DoesNotExistOnWMException {
00133 try {
00134 return getVersionNumber(_id, getSubarchitectureID());
00135 } catch (UnknownSubarchitectureException e) {
00136 throw new RuntimeException(
00137 "Shouldn't happen on own subarchitecture", e);
00138 }
00139 }
00140
00155 public int getVersionNumber(String _id, String _subarch)
00156 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00157
00158 assert _id.length() > 0 : "id must not be empty";
00159 assert _subarch.length() > 0 : "subarchitecture id must not be empty";
00160 assert m_workingMemory != null;
00161
00162 return m_workingMemory.getVersionNumber(_id, _subarch);
00163 }
00164
00182 public int getVersionNumber(WorkingMemoryAddress _wma)
00183 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00184 return getVersionNumber(_wma.id, _wma.subarchitecture);
00185 }
00186
00194 protected final void storeVersionNumber(String _id, int _version) {
00195 m_versionNumbers.put(_id, _version);
00196 }
00197
00206 public final int getStoredVersionNumber(String _id)
00207 throws ConsistencyException {
00208
00209 Integer v = m_versionNumbers.get(_id);
00210 if (v == null) {
00211 throw new ConsistencyException("No stored version for id: " + _id,
00212 new WorkingMemoryAddress(_id, getSubarchitectureID()));
00213 } else {
00214 return v;
00215 }
00216 }
00217
00223 protected final void startVersioning(String _id) {
00224 assert (!isVersioned(_id));
00225 storeVersionNumber(_id, 0);
00226 }
00227
00234 protected final void updateVersion(String _id, int _newVersion) {
00235
00236
00237
00238
00239
00240
00241
00242
00243 storeVersionNumber(_id, _newVersion);
00244 }
00245
00254 protected final void increaseStoredVersion(String _id)
00255 throws ConsistencyException {
00256 int stored = getStoredVersionNumber(_id);
00257 updateVersion(_id, ++stored);
00258 }
00259
00266 public final boolean isVersioned(String _id) {
00267 return m_versionNumbers.containsKey(_id);
00268 }
00269
00275 protected final void stopVersioning(String _id) {
00276 if (isVersioned(_id)) {
00277 removeVersionNumber(_id);
00278 }
00279 }
00280
00286 protected final void removeVersionNumber(String _id) {
00287 m_versionNumbers.remove(_id);
00288 }
00289
00301 public final boolean haveLatestVersion(String _id)
00302 throws ConsistencyException, DoesNotExistOnWMException {
00303 assert (isVersioned(_id));
00304
00305 int ownedVersion = getStoredVersionNumber(_id);
00306 int wmVersion = getVersionNumber(_id);
00307
00308 return wmVersion == ownedVersion;
00309 }
00310
00321 public final void checkConsistency(String _id) throws ConsistencyException,
00322 DoesNotExistOnWMException {
00323 try {
00324 checkConsistency(_id, getSubarchitectureID());
00325 } catch (UnknownSubarchitectureException e) {
00326 throw new RuntimeException(
00327 "Shouldn't happen on own subarchitecture", e);
00328 }
00329 }
00330
00342 public void checkConsistency(String _id, String _subarch)
00343 throws ConsistencyException, DoesNotExistOnWMException,
00344 UnknownSubarchitectureException {
00345
00346 if (!isVersioned(_id)) {
00347 throw new ConsistencyException("!isVersioned(" + _id
00348 + ") in subarch " + _subarch, new WorkingMemoryAddress(_id,
00349 _subarch));
00350 }
00351
00352 if (!haveLatestVersion(_id, _subarch)) {
00353 throw new ConsistencyException(
00354 "You have attempted to overwrite an outdated working memory entry. Please reread and try again. WMA: "
00355 + _id
00356 + ":"
00357 + _subarch
00358 + ". Local version: "
00359 + getStoredVersionNumber(_id)
00360 + ". WM version: "
00361 + getVersionNumber(_id, _subarch),
00362 new WorkingMemoryAddress(_id, _subarch));
00363 }
00364
00365 }
00366
00380 public boolean haveLatestVersion(String _id, String _subarch)
00381 throws ConsistencyException, DoesNotExistOnWMException,
00382 UnknownSubarchitectureException {
00383 assert (isVersioned(_id));
00384
00385 int ownedVersion = getStoredVersionNumber(_id);
00386 int wmVersion = getVersionNumber(_id, _subarch);
00387
00388 debug("id: " + _id + "own: " + ownedVersion + " wm: " + wmVersion);
00389 return wmVersion == ownedVersion;
00390 }
00391
00405 public void checkConsistency(WorkingMemoryAddress _wma)
00406 throws ConsistencyException, DoesNotExistOnWMException,
00407 UnknownSubarchitectureException {
00408 checkConsistency(_wma.id, _wma.subarchitecture);
00409 }
00410
00421 public void lockEntry(String _id, String _subarch,
00422 WorkingMemoryPermissions _permissions)
00423 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00424
00425 assert _id.length() != 0 : "id must not be empty";
00426 assert _subarch.length() != 0 : "sa must not be empty";
00427 assert m_workingMemory != null;
00428
00429
00430 m_workingMemory
00431 .lockEntry(_id, _subarch, getComponentID(), _permissions);
00432 m_permissions.setPermissions(_id, _subarch, _permissions);
00433 }
00434
00443 public void lockEntry(WorkingMemoryAddress _wma,
00444 WorkingMemoryPermissions _permissions)
00445 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00446 lockEntry(_wma.id, _wma.subarchitecture, _permissions);
00447 }
00448
00457 public void unlockEntry(WorkingMemoryAddress _wma)
00458 throws ConsistencyException, DoesNotExistOnWMException,
00459 UnknownSubarchitectureException {
00460 unlockEntry(_wma.id, _wma.subarchitecture);
00461 }
00462
00473 public void unlockEntry(String _id, String _subarch)
00474 throws ConsistencyException, DoesNotExistOnWMException,
00475 UnknownSubarchitectureException {
00476 assert _id.length() != 0 : "id must not be empty";
00477 assert _subarch.length() != 0 : "sa must not be empty";
00478 assert m_workingMemory != null;
00479
00480
00481 if (!holdsLock(_id, _subarch)) {
00482 debug("no lock held for: " + _id + ":" + _subarch);
00483 return;
00484 }
00485
00486 assert (_id.length() != 0);
00487
00488
00489 m_workingMemory.unlockEntry(_id, _subarch, getComponentID());
00490
00491 m_permissions.removePermissions(_id, _subarch);
00492
00493
00494 assert (!holdsLock(_id, _subarch));
00495
00496 }
00497
00510 public boolean tryLockEntry(String _id, String _subarch,
00511 WorkingMemoryPermissions _permissions)
00512 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00513 assert _id.length() != 0 : "id must not be empty";
00514 assert _subarch.length() != 0 : "sa must not be empty";
00515 assert m_workingMemory != null;
00516
00517
00518 boolean succeeded = m_workingMemory.tryLockEntry(_id, _subarch,
00519 getComponentID(), _permissions);
00520
00521
00522 if (succeeded) {
00523 m_permissions.setPermissions(_id, _subarch, _permissions);
00524 }
00525
00526 return succeeded;
00527
00528 }
00529
00540 public boolean tryLockEntry(WorkingMemoryAddress _wma,
00541 WorkingMemoryPermissions _permissions)
00542 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00543 return tryLockEntry(_wma.id, _wma.subarchitecture, _permissions);
00544 }
00545
00555 public WorkingMemoryPermissions getPermissions(String _id, String _subarch)
00556 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00557 assert _id.length() != 0 : "_id must not be empty";
00558 assert _subarch.length() != 0 : "_subarch must not be empty";
00559 return m_workingMemory.getPermissions(_id, _subarch);
00560 }
00561
00571 public WorkingMemoryPermissions getPermissions(WorkingMemoryAddress _wma)
00572 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00573 return getPermissions(_wma.id, _wma.subarchitecture);
00574 }
00575
00588 public boolean isOverwritable(String _id, String _subarch)
00589 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00590 if (holdsOverwriteLock(_id, _subarch)) {
00591 return true;
00592 } else {
00593 WorkingMemoryPermissions permissions = getPermissions(_id, _subarch);
00594
00595
00596 return CASTUtils.overwriteAllowed(permissions);
00597 }
00598 }
00599
00610 public boolean isDeletable(String _id, String _subarch)
00611 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00612 if (holdsDeleteLock(_id, _subarch)) {
00613 return true;
00614 } else {
00615 WorkingMemoryPermissions permissions = getPermissions(_id, _subarch);
00616 return CASTUtils.deleteAllowed(permissions);
00617 }
00618 }
00619
00630 public boolean isReadable(String _id, String _subarch)
00631 throws DoesNotExistOnWMException, UnknownSubarchitectureException {
00632 if (holdsReadLock(_id, _subarch)) {
00633 return true;
00634 } else {
00635 WorkingMemoryPermissions permissions = getPermissions(_id, _subarch);
00636 return CASTUtils.readAllowed(permissions);
00637 }
00638 }
00639
00647 public void unlockEntry(String _id) throws ConsistencyException,
00648 DoesNotExistOnWMException {
00649 try {
00650 unlockEntry(_id, getSubarchitectureID());
00651 } catch (UnknownSubarchitectureException e) {
00652 throw new RuntimeException(
00653 "Shouldn't happen on own subarchitecture", e);
00654 }
00655 }
00656
00669 public void lockEntry(String _id, WorkingMemoryPermissions _permissions)
00670 throws DoesNotExistOnWMException {
00671 try {
00672 lockEntry(_id, getSubarchitectureID(), _permissions);
00673 } catch (UnknownSubarchitectureException e) {
00674 throw new RuntimeException(
00675 "Shouldn't happen on own subarchitecture", e);
00676 }
00677 }
00678
00691 public void tryLockEntry(String _id, WorkingMemoryPermissions _permissions)
00692 throws DoesNotExistOnWMException {
00693 try {
00694 lockEntry(_id, getSubarchitectureID(), _permissions);
00695 } catch (UnknownSubarchitectureException e) {
00696 throw new RuntimeException(
00697 "Shouldn't happen on own subarchitecture", e);
00698 }
00699 }
00700
00701
00702
00711 public boolean isOverwritable(String _id) throws WMException {
00712 if (holdsOverwriteLock(_id)) {
00713 return true;
00714 } else {
00715 WorkingMemoryPermissions permissions = getPermissions(_id);
00716 return CASTUtils.overwriteAllowed(permissions);
00717 }
00718 }
00719
00728 public boolean isDeletable(String _id) throws WMException {
00729 if (holdsDeleteLock(_id)) {
00730 return true;
00731 } else {
00732 WorkingMemoryPermissions permissions = getPermissions(_id);
00733 return CASTUtils.deleteAllowed(permissions);
00734 }
00735 }
00736
00745 public boolean isReadable(String _id) throws WMException {
00746 if (holdsReadLock(_id)) {
00747 return true;
00748 } else {
00749 WorkingMemoryPermissions permissions = getPermissions(_id);
00750 return CASTUtils.readAllowed(permissions);
00751 }
00752 }
00753
00761 public WorkingMemoryPermissions getPermissions(String _id)
00762 throws WMException {
00763 try {
00764 return getPermissions(_id, getSubarchitectureID());
00765 } catch (UnknownSubarchitectureException e) {
00766 throw new RuntimeException(
00767 "Shouldn't happen on own subarchitecture", e);
00768 }
00769 }
00770
00778 public boolean holdsLock(String _id) {
00779 return holdsOverwriteLock(_id);
00780 }
00781
00790 public boolean holdsLock(String _id, String _subarch) {
00791 return holdsOverwriteLock(_id, _subarch);
00792 }
00793
00801 public boolean holdsOverwriteLock(String _id) {
00802
00803 return m_permissions.getPermissions(_id) != null;
00804 }
00805
00813 public boolean holdsDeleteLock(String _id) {
00814 WorkingMemoryPermissions permissions = m_permissions
00815 .getPermissions(_id);
00816 return permissions != null
00817 && (permissions == WorkingMemoryPermissions.LOCKEDOD || permissions == WorkingMemoryPermissions.LOCKEDODR);
00818 }
00819
00827 public boolean holdsReadLock(String _id) {
00828 WorkingMemoryPermissions permissions = m_permissions
00829 .getPermissions(_id);
00830 return permissions != null
00831 && permissions == WorkingMemoryPermissions.LOCKEDODR;
00832 }
00833
00842 public boolean holdsOverwriteLock(String _id, String _subarch) {
00843
00844 return m_permissions.getPermissions(_id, _subarch) != null;
00845 }
00846
00855 public boolean holdsDeleteLock(String _id, String _subarch) {
00856 WorkingMemoryPermissions permissions = m_permissions.getPermissions(
00857 _id, _subarch);
00858 return permissions != null
00859 && (permissions == WorkingMemoryPermissions.LOCKEDOD || permissions == WorkingMemoryPermissions.LOCKEDODR);
00860 }
00861
00870 public boolean holdsReadLock(String _id, String _subarch) {
00871 WorkingMemoryPermissions permissions = m_permissions.getPermissions(
00872 _id, _subarch);
00873 return permissions != null
00874 && permissions == WorkingMemoryPermissions.LOCKEDODR;
00875 }
00876
00877 protected boolean needsConsistencyCheck(String _id) {
00878 return m_permissions.needsConsistencyCheck(_id);
00879 }
00880
00881 protected boolean needsConsistencyCheck(String _id, String _subarch) {
00882 return m_permissions.needsConsistencyCheck(_id, _subarch);
00883 }
00884
00885 protected void consistencyChecked(String _id) {
00886 m_permissions.consistencyChecked(_id);
00887 }
00888
00889 protected void consistencyChecked(String _id, String _subarch) {
00890 m_permissions.consistencyChecked(_id, _subarch);
00891 }
00892
00893 }