SECOND CORE OF THE PROGRAM -
This package contains the classes which provide the search of rights and access paths in the open gBase views. It contains also « facade » classes for the ACS and the views.
This gWork package contains the algorithms of the generic (or core) access paths search (or rights search). The first aim is to detect the CNot.DisplayableLinkImpls of a view, modeling the view access paths. The gWork packages offer complex pipelines for detecting, manipulating and filtering the DisplayableLinkImpls, in a mandatory sequence of calls. The DisplayableLinkImpls are the visible result of a Gui2.GraphicalView, that handles the image of its gBase view in the GUI. The NoMore-NoLess view uses DisplayableLinkImpls without displaying them. The Sketch view shows the DisplayableLinkImpls without 'See Why' text. The classes of this generic package may be extended in the gWork packages of the AcsAddons.
THE ACCESS ROAD WAY OF DESIGN
Generally speaking, the Access Road software is based on a solid object-oriented design. The best way to provide great software at the best cost is to concentrate the efforts on clear and structured data, clear and structured patterns, clear and structured documentation, in varied layers of abstraction. This is an iterative structure-driven and abstraction-driven development process, rather than a test-driven process. This approach is presented in the gBase package documentation.
We love the idea of a strong database model from which the software structures and the algorithms emerge, since this is the true nature of a simulation software. This is also true for the path search algorithms. They are the most complex part of the Access Road code. An access path is modeled by the DisplayableLinkImpl class, into the CNot package. The first property of a DisplayableLinkImpl is to contain from 2 to N nodes. The concept of access link between two near path nodes is modeled by the CNot.AccessControlLinkImpl class. For example, if a given node N has an 'owner' (indeed, an account modeled as an UserID), then the paths search structure has to include one or several specialized methods to analyse the path nodes for detecting this 'owner' relation after the node N, and to set it into an AccessControlLinkImpl instance. The classes and methods in the gWork package to find all the applicable paths are so based on the semantic geometry of the possible links between the path nodes, and then, they derive from the concepts of the database model. The expressive power and extensibility of this architecture is a key factor of success for Acces Road.
THE MAIN CLASSES
The generic gWork classes of this package are presented hereinafter:
The ACS of the gBase packages are built up by the AcsFactory classes. There is a generic AcsFactory class in this package. At the request of gDMak.ActionNewACSyst, an AcsFactory creates and configures an instance of gBase.ACSFActoryImpl. This ACSFactory object creates the new ACS instance for the AcsFactory.
AclRightsFactoryImpl is a class for the generic processing of Access Control Lists and Bridges. AgoRightsFactoryImpl is a class for the Account/Group and bridge rights, and for the data exchange links. PrivilegeRightsFactoryImpl is a class for the PrivilegeForType and PrivilegeForLinks rights. ThreeNodesRightsFactoryImpl handles all the 3-nodes paths, processing all the types of rights and relations. CompoundRightsFactoryImpl is the most complex class for searching the access paths of more than 3 nodes. It has also some specialized methods about specific relations like Bridges, VirtualMembers, Aliases and ContextSwitches.
RightsMediatorImpl is responsible for listening the property changes in all the nodes and the intermediate nodes of a view. The aim is to detect when such a change requires an updating of the view, on its nodes or its access paths. This class has also the responsibility to manage the core algorithms instances of its view - see the thread management.
There are several levels of methods for the access paths processing. Some methods are dedicated to the search of the simple 2-nodes access paths, or DisplayableLinkImpls. Another level is for the methods dedicated to one ACSObject, and they are in NodeRights. The last level is in LinkRightsImpl for handling the priorities among the rights, like through a filtering of the access paths. There is also a set of common methods that are called from these different levels, including varied general utilities on access paths and rights.
The generic rights processing in this package is designed to be overridden or changed for the rights processing in each AcsAddon. An AcsAddon may add a complementary processing to each view node that has a gBase class from the AcsAddon. In the AcsAddon, this is done in the subclasses of the two generic classes NodeRightsImpl and LinkRightsImpl. They offer about 50 methods. It is possible to code varied hooks in these subclasses, for which the methods are empty in the generic classes.
THE gBase VIEWS
ViewInBaseImpl and its subclasses contains the data to save from the views. A view is a passive container on which Access Road processes an extended search to find the access paths between the nodes of the view. These paths are transient data that is updated each time a relevant property is changed in the gBase packages. There are several types of views:
ViewInBaseImpl is a subclass of FolderAbs, which is also the superclass of VirtualFolderImpl. The relation ViewInBase/member is weak, since the deleting of the container or the member does not delete the other entity.
ViewInBaseImpl has 3 subclasses, EPRViewInBaseImpl, NoThanViewInBaseImpl and SketchViewInBaseImpl. These classes are responsible for modeling a set of BaseObjects for which the GUI may provide an ARoad0.Gui2.GraphicView.
ARoad0.Gui2.GraphicView displays the current rights and links between any couple of view objects, or nodes. There is a 1:1 relation between an open ViewInBase and its GraphicView, if any.
The ViewInBases in the gBase package do not handle the rights and the links, but only the nodes in the view.
EPRViewInBaseImpl is a subclass of ViewInBaseImpl. As GraphicView, it uses an ARoad0.Gui2.GraphicEPRView. It is the most general view, because it provides the search of all the paths between all the nodes of the views. It stores the nodes and listens some basic property changes to inform its GraphicView. Such a view may be opened without been displayed in a GraphicView.
NoThanViewInBaseImpl is a subclass of EPRViewInBaseImpl. As GraphicView, it uses an ARoad0.Gui2.GraphicNoThanView. It checks up the compliance with the rights upon 2 optional rules : a maximum right and a minimum right. For each of these two criteria, the search of paths stops when it finds one path where the criterion is not fulfilled. This view stores the nodes and listens some basic property changes to inform its GraphicView. Such a view may be opened without been displayed in a GraphicView.
SketchViewInBaseImpl is also a subclass of EPRViewInBaseImpl. It has for GraphicView an ARoad0.Gui2.GraphicSketchView. It does not listen the property changes of the nodes. Such a view is never opened without a GraphicSketchView, and it is never saved.
The other package classes may listen the property changes in the gBase objects. The generic gBase package uses only the interfaces of the gBaseInterface package. Most of the classes in the generic gBase package are designed to be overridden in the AcsAddon gBase packages. There is a dedicated interface the AcsAddons use to declare the specific property changes the other packages have to listen on their AcsAddon objects.
OVERVIEW OF THE gWork PACKAGES
The gWork packages are intend to build up the graphs of access paths between the nodes of any kind of Gui2.GraphicView. A GraphicView handles the image of its gBase view in the GUI. The gWork packages are also intend to produce the 'See why' text of a GraphicView, from the graphs of access paths. It has to update this data at every relevant change of the gBase properties. Each gBase view has 0 to 1 associated GraphicView. The main task of a GraphicView is to display the diagram of its gBase view, including a representation of the view nodes and a summary of the access paths. A GraphicView has always one main gBase view, but a GraphicNoThanView is a kind of GraphicView which needs to create temporary, non-saved gBase views to find its access paths. The gBase views are totally independant. It is possible to have 2 gBase views having exactly the same ACSObjects. 'GraphicView' and 'gBase view' are 2 terms which are often equivalent into this documentation, like 'access path', 'displayable link' and 'DisplayableLinkImpl'.
The intuitive reading of a full view diagram by the user is an important requirement. This is called the 'smart' reading of the user eye, and it should be complex to get. If there is an arrow from the view node A to the view node B, and a second arrow from B to the view node C, then the user 'reads' without questions an indirect access path from A to C. The Access Road diagram in a full view, modeled as a GraphiEPRView, takes account of this natural behavior of the user. However, if such an indirect path is not true, an additional path is required from A to C to tell the user: 'this is a forbidden path'. Providing a smart reading may be much more complex, as we will see with the ContextSwitches (new in 0.7.3).
The classes of any gWork package, from an AcsAddon or from the generic package, handle all the entities and concepts of the generic package gBase. The classes of an AcsAddon package gWork deal with all the specific gBase entities and concepts of its AcsAddon. The classes of any gWork package use the CNot package, where the access paths are modeled. An AcsAddon cannot overread the CNot package classes. The searchs in the generic gWork package are based on the interfaces of gBaseInterface. It may proceed the gBase entities of the AcsAddons.
For a given view, finding an access path means creating or copying/extending an instance of CNot.DisplayableLinkImpl. The gWork packages provides the search always from the access sources to the access targets. When a DisplayableLinkImpl of N nodes has to be extended by a new node, it is copied then extended to produce a link of N+1 or N+2 nodes. Before the release 0.7.3, the work to find the new nodes was simplified by the fact that the new nodes are selected from the two last nodes of the access path. With 0.7.3, they depends also on the general properties of the DisplayableLinkImpl, and for the ContextSwitch links, they depends on all its nodes, and even on all the DisplayableLinkImpls detected between all the nodes of the view. Between 2 view nodes, a gWork package may create a DisplayableLinkImpl having from 2 to 42 nodes. There is no limit to the number of DisplayableLinkImpls between 2 view nodes. If they are too numerous, they may not be displayed in the 'See why' text of the EPR view.
The generic gWork package is designed, coded and tested to be used for all the possible states of ACSObject from the generic gBase package. This includes 8 main gBaseInterface.ACSObject instances (Resource, Directory, VirtualFolder, Actor, UserID, GroupID, ExchangePoint, ContextSwitch), and 3 rights modeled as classes (AclEntry, PrivilegeForLinks and PrivilegeForType). The other rights are modeled as ACSObject properties: Resource AG rights, Actor Bridge rights, EndPoint senders lists, ExchangePoint maximal rights of ends, and finally, the Account/Group, AclEntry and PrivilegeForLinks inherited rights. Varied structural relations are also modeled in the database, like the ownership of an ACSObject or its aliasing. This generic package uses the properties of a generic ACS for driving the ACSObject behavior.
For parsing the possible paths from an intermediate DisplayableLinkImpl, one or several types are selected among the 21 relation types into CNot.AccessControlLinkImpl. During the search, a DisplayableLinkImpl may have a current Account/Groups context. It drives the choice of some extensions for this DisplayableLinkImpl. This AG context has a known position on one node of the link. For a given view, most of the algorithms in this generic gWork package are not used, since the processing is based on the true properties of each node in the DisplayableLinkImpl. The access paths are detected at the request of the Gui2.GraphicView. This defines a set of interfaces, classes and behaviors which is called the access path pattern.
This gWork package contains some POJO classes, based on a classic object-oriented design. Nonetheless, the gWork packages are rather grounded on functional programming. Most of the classes xxxRightsFactoryImpl are stateless. Their methods implement pure functions. The only inner variables are the instances of the other xxxRightsFactoryImpl classes which collaborate. Except for CompoundRightsFactoryImpl, all the properties to update are in the method arguments. Functions are without secondary effects, since there is no instance property to update.
For all the methods in the gWork packages, the main argument is the map of the current DisplayableLinkImpls. It is usually named _m_l_DisplayableLinks (or _upd_m_l_DisplayableLinks to tell it may be updated by the method). At each method call, this map may be filled with new DisplayableLinkImpls. The class RightsFactory_Facade is responsible to manage the sequence of method calls in the access paths search, through the generic and AcsAddon gWork classes. At the end of the search, Gui2.GraphicView reads the map to display the links and arrows in the diagram, and to call the RightsFactory_Facade methods dedicated to the creation of the 'See why' text.
There are varied application contexts for the paths search methods:
For a gBase.EPRViewInBase class, RightsFactory_Facade passes on the called methods the view and its graphic view as arguments.
For a gBase.NoThanViewInBase class, RightsFactory_Facade passes on to the called methods a transient EPRViewInBase and the graphic view of the initial NoThanViewInBase. Each transient view contains a pair of nodes from the NoThanViewInBase to analyze, with one EligibleParty and the first target.
For a gBase.SketchViewInBase class, RightsFactory_Facade passes on the classical arguments, like for an EPRViewInBase, but for a view which has been filled by the method ViewInBase_Facade.populateSketchView().
The classes in the generic gWork package are designed following the design pattern Visitor, from the GoF design patterns collection. The package is organized by right type (AG, ACL, ...), and by path size. The gWork package is well structured, not only at the class level, but also in the body of the large methods it is necessary to have. Into the functional style, patterns of code are used and reused, and it is recommended to keep them in the future evolutions.
The full view diagram and the 'See why' text are generally consistent. There are some exceptions, like for example the MySQL server AcsAddon for a full view. When it finds a 3-nodes path like GroupID/acl/Actor/run_under/GroupID, since such a path has no effect, it is not visible in a view diagram, although it is put in the 'See Why' text of the view. The only case where the 'See Why' text does not display fully the set of DisplayableLinkImpls is when too many paths contain the same 3-nodes sequence, for a couple of view objects. This gives an uselessly large list of DisplayableLinkImpls. For such a view couple, a limited number of these paths are displaying in the 'See Why' text.
Generally speaking, this release 0.7.3 increases the complexity of the access paths. Between two components, the number of types of generic access paths having exactly 3 nodes expands by 70 to 100 types. This is mainly due to the classes ExchangePoint and ContextSwitch, and to the Alias relation. The behavior of a ContextSwitch forces to call several times the central method CompoundRightsFactoryImpl.detectHiddenCompoundEpRightsForDLinks() to detect all the switchings of AG context. About this very large method, its inner complexity is the image of the complex algorithms to implement.
OVERVIEW OF THE TEST STRATEGY
The data-centric approach is applied to the path search algorithms, the most complex part of the code. The path search algorithms are implemented through a functional programming approach, using large static methods. Very large methods with numerous loops are sometimes mandatory for providing the fastest implementations. These methods are strongly structured, to facilitate their editing.
Here is a rule for driving all the tests on the searching of access path. Whatever the size of an access path (2 nodes, 3 nodes or more), the result must be consistent. Typically, if there is a path A-B-C-D, then the following paths must also exist in the relevant views : A-B, B-C, C-D, A-B-C, B-C-D. On the other hand, if there are the paths A-B-C and C-D, then the path A-B-C-D may have to be found in a view which contains A and D, but only if C is such a 'proxy' node. This is not true in the inverse sens: due mainly to the class ContextSwitch, a large path may not be directly derived from the sum of the 2-nodes paths. To test the access path searching, it is recommanded to use a scale of paths from 2-nodes paths to paths of 5 nodes. This rule helps to get a more reliable code.
The intermediate-data testing is able to test efficiently large constructors and large methods, contrary to the classical way. A first general mean to monitor the internal data for testing requires simply to print them during the execution of the code. 'System.out.println()' calls are required. The Access Road code is full of such calls the code maintainer may easily enable and disable at any moment. The beauty of this testing approach is that no heavy development tool is needed, but a text editor, a Java compiler, and above all, the clear mind of a skilled developer. A second way to monitor the internal data for testing is to read the access paths of a view, because this contain useful descriptions about the paths search logic. The gWork packages uses a functionnal-programming style in the access paths search. A detailled human review of the view paths is an efficient way against bugs. Some comparisons between the access paths from two successive versions of Access Road may also be powerful to help the developer to trully understand its new code. We love the continous testing approach through automated tests based on a risk analysis. The previous principles may be seen as an extension of this best practice. It is easy to convert the 'System.out.println()' calls into calls to a BaseError instance, to collect all the execution points and to use them as criteria of some automated integration tests, or, as Google says, medium-size tests. These criteria complete the classical set of input/output test data. The automated non-regression tests use such input/output test data. They are presented later in this overview.
THE ARCHITECTURAL PATTERNS
Several architectural patterns have emerged during the Access Road development, even if they are not always fully presented as pattern in the code documentation:
The little decision maker pattern in the gDMak package is responsible to manage the basic operations from the events of the menu.
The little internal frame pattern in the Gui1 package is responsible to handle the internal frames in the Access Road desktop.
The gBaseBeanInfo package applies an extended JavaBean pattern called the BeanInfoPattern, to set the handling of gBase objects in the GUI. This pattern covers the display of each property of the base object in the right GUI editor, and the policy to create, edit and delete the property. It is applied mainly by the gBaseBeanInfo and the Gui1 packages.
The embedded class pattern provides a form of multiple class inheritance for the classes in the gBase packages.
The event management pattern for the views is responsible to update a displayed view when a relevant property is changing, from a view node or an intermediate node in any access path of the view. It is described in the documentation of Gui2.GraphicViewBaseListener.
The thread management pattern for the views is responsible to provide a dedicated thread to each displayed view, for processing its own access path searches. This complex pattern is presented in a dedicated section.
The access path search pattern is the most complex one. It includes mainly the generic gWork package and the AcsAddon gWork packages which contain the search algorithms. There is also the Gui2 package with the GraphicViews, and the CNot package which contains the notification interfaces and classes for the data flow between the gWork packages and the GUI-oriented packages. This complex pattern is presented in a dedicated section.
The pattern for the AcsAddons is explicit and well documented, covering the coding for each of the classes and methods which belong to it. It is mainly implemented in the gBase and the gWork packages. This pattern allows to add easily some Java classes to do specific gBase and gWork functions. More precisely, it inserts "hooks" (upcalls to the AcsAddon code, through overridden methods) at every point in the generic code where the concept or the algorithm is about to result in product a wrong simulation of access control. This complex pattern is presented in a dedicated section.
As a framework for simulators, Access Road needs to offer all these architectural patterns. It provides powerful capacities to simulate a new software, and to integrate it into the GUI and into the other simulations. Interface multiple inheritance, Java reflection in Java and dependency injection are used extensively in the patterns. On the other hand, Java annotations and aspects are never used. They have not proved their usefulness yet. The OSGi standard is much more complex than the AcsAddons pattern. It is not used mainly because the loading of a Java module during the Access Road execution is not a need.
THE ACCESS PATHS SEARCH PATTERN
The paths search is always from the source to the target. For processing the large paths, the DisplayableLinkImpls list of a view grows up like a bunch of flowers, where the new stalks are longer and longer. At the end, only the 'flowers' which belong to the view remain, and the result appears like a spindle-shaped bunch. A second search in the sens target-to-source would improve the search speed, but this is not done for the moment. Nonetheless, the most complex paths in CompoundRightsFactoryImpl may be found through a reverse search from the view nodes, but only for the last couple of nodes.
The generic gWork package is associated in the GUI to the Gui2.GraphicView and its subclasses. They are responsible to display the DisplayableLinkImpls all the gWork packages provide. Gui2.GraphicView and its subclasses also belong to the access path pattern. This generic gWork package contains all the complex and immutable algorithms of search. Searching the large paths is the responsability of the method detectHiddenCompoundEpRightsForDLinks(), in the class gWork.CompoundRightsFactoryImpl. It is the most complex method of the program, with about 1000 lines of code. It is also one of the rare methods to be invoked in an iteration, for handling the ContextSwitch paths.
The method detectHiddenCompoundEpRightsForDLinks() is presented in this paragraph. A DisplayableLinkImpl to extend cannot contain twice a given node. It may contain a view node as intermediate node. The basic search deep is 41. This means some DisplayableLinkImpls of up to 41 nodes may be find through the central iterations of this method, at each call. Moreover, handling the ContextSwitches requires to consider the ability of RightsFactory_Facade.detectEPRRights() to call this method up to 40 times. This defines the second and third mode of use for this method, as it is explained in its documentation (new in 0.7.3). The purely theorical search deep is up to 1600 hidden or non-hidden nodes, to find one DisplayableLinkImpl in a view. To be fast and maintenable, this method is based on very structured loops that could be seen as elementary blocks. There are 2 main steps in this method: the central iterations and the final iterations. The central search iterations extend some DisplayableLinkImpls in 4 continuous loops that ends only when there is no new hidden node to add at the end of the current path. This implies the test of 19 cases, with a search for 7 cases of GroupIDMembers, a search on 7 cases of Actors, a search for 4 cases of EP Virtualfolders, and a search for 1 case of Resource aliases. These tests include 3 tests on the hooks for the AcsAddons on Actors, GroupIDMembers and VirtualFolders. The final search iterations have to end a DisplayableLinkImpl with a view node. This requires the test of 14 cases, including 4 hooks for the AcsAddons. There are also 3 final filterings to reject some DisplayableLinkImpls for applying the priority rules among the Virtualfolders, the AGO, PRI and ACL rights.
The search pattern is presented hereinafter. The aim is to find, for a given DisplayableLinkImpl, what are the possible extensions with a new second end. As we have seen for the 19 central cases to test into the method detectHiddenCompoundEpRightsForDLinks(), the new nodes to connect depend mainly on the ACSObject A that is the current second end of the link. The principles of the search are summarized hereinafter:
The nature and the properties of the ACSObject A defines the methods to call in the search of a new extension of the current access path. The nature and the properties of A also define the types of link this path extension may have, in the context of its ACS. If A is an UserID in an ACS managing the Account and the Account Rights, a possible path extension will be the owning relation on any Resource this UserID owns.
The path extension is added at the end of the current DisplayableLinkImpl having A as second node, if it is compatible to the properties of the current DisplayableLinkImpl nodes. This defines new DisplayableLinkImpls which are added to the map of the current DisplayableLinkImpls of the view. The last AccessControlLink of a new DisplayableLinkImpl describes the nature of the new relation, while the other AccessControlLinks and nodes are copied from the initial DisplayableLinkImpl. A searching method may sometimes update a current DisplayableLinkImpl (e.g. to add a comment) whitout extension of the path.
These paths are passed on from searching method to searching method in a map generally called _m_l_DisplayableLinks or _upd_m_l_DisplayableLinks. They are most often stateless methods with an API coded in a functional programming style, that is where the method arguments may be updated by the method (note: this is not the standard Java style of coding). These search methods are in dedicated gWork classes following the nature of the relation to find, like AclEntries or Privileges, or the size of the path. This is why the 3-nodes paths are found by a dedicated ThreeNodesRightsFactoryImpl class, while the paths greater than 3 nodes are also searched by a dedicated gWork CompoundRightsFactoryImpl class. In this search pattern, the hierarchy of classes is used only for creating the AcsAddon algorithms.
Generally speaking, the access path search ends for a given source node in the view, (1) when the DisplayableLinkImpl from the source node has a second end belonging to the view, (2) when there is no more relation to discover from the current second end, or (3) if the number of nodes in the DisplayableLinkImpl is greater than 40.
Some filtering methods exist at different steps of the search to remove a DisplayableLinkImpl when a priority rule has to be fulfilled, like between the UserID 'A rights' and the GroupID 'G rights'.
The concept of no-right-proxy on an Actor is used to forbid this Actor to be an intermediate node into any access path. This property does not depend on the AG context of the Actor, nor on its general abilities following its nature or the rights on it. Because a no-right-proxy Actor enforces all the proxy features are unset, the user should use this property very carefully.
The concept of executing right on an Actor is used to allow this Actor to be an intermediate node for most of the type links. There are some exceptions, like the Alias link which does not require any executing right. An executing right may NOT be associated to the metaright 'execute'. The MySQL right 'CREATE' is associated to the metaright 'write', but it is the upper right of the MySQL right 'EXECUTE' for which the metaright is 'execute'. So, the MySQL right 'CREATE' is indeed an executing right to simulate properly the logic of the MySQL rights.
An important feature of the access path search is the handling of the Account/Groups context. The method DisplayableLinkUtilities.getSecondEndAGcontext() updates and returns the current AG context of the second end of a DisplayableLinkImpl. Typically, if an Actor runs under an UserID, this UserID belongs to the Actor AG context, when this Actor is the second end of a DisplayableLinkImpl modeling an access path. The access path search has then to extend this DisplayablelinkImpl by the relevant UserID, using an activated type RUN_UNDER as relation from the Actor to the UserID. The current AG context is indeed the value of the key DisplayableLinkImpl.AG_CONTEXT into the DisplayableLinkImpl properties map. It is a set of GroupIDMembers that may contain, first, an optional couple (UserID, GroupID), and, second, a list of optional GroupIDs. If the property for the DisplayableLinkImpl.AG_CONTEXT_NODE_POSITION is the position of the second end, the method getSecondEndAGcontext() returns the current AG context, and it does not change the displayable link. Otherwise, it is updated. Changing the current Account/Groups context, from node to node into the displayable link, is mainly drived by the activated types of the previous AccessControlLink, the interfaces between the ACS, and some properties of the Actors. To summarize them for an Actor 'A', that is one of the most complex cases, here is the main cases to consider for a link into a generic ACS:
EligibleParty/AclEntry/'A' as Actor: no AG context change,
Privilege source/Privilege/'A' as Privilege target: the AG context becomes the current UserID/GroupID of 'A', plus the secondary groups,
master program/pure data exchange/'A' as ExchangePoint: the master program AG context is kept,
ExchangePoint/pure data exchange/'A' as master program: the AG context becomes the current UserID/GroupID of 'A', plus the secondary groups,
any source/GLOBAL only as activated type/'A' as any target: the AG context becomes the current UserID/GroupID of 'A', plus the secondary groups,
any other activated types (like OWNER, RUN_UNDER...): no AG context change.
Before the release 0.7.3, an EPR view having 3 nodes A, B and C may produce any couple of paths between (A, B), (A, C) and (B, C), but the paths for example for (B, C) never depend on the paths on (A, B). The concept of ContextSwitch changes that. With a ContextSwitch, the following nodes in an access path may depend on the previous nodes in the path, before the ContextSwitch, even if these previous nodes are separated from the ContextSwitch by 20 intermediate nodes. The previous '0.7.2' search handles this behavior properly when all the intermediate nodes are hidden in a view, but this is much more complex if some of them are view nodes. On the other hand, offering a 'smart' reading to the user eye is a very important requirement. This method helps to improve the algorithms of access paths search for an EPR view. Let's say we have an access path A-B-C-D-CSW-E-F, where the letters A from F are path nodes, and CSW is a ContextSwitch path node. This path (A, F) is directly displayed in the EPR view contains only the ACSObjects A and F. The other objects are hidden nodes in the path of this view. In that case, there is no additional feature to create. On the other hand, the view may contain A, CSW and F. The gWork packages find all the paths (A, CSW), including A-B-C-D-CSW, and all the paths (CSW, F), including CSW-E-F. But the path A-B-C-D-CSW is never extended to find F, since CSW is a view node. This stops the previous 0.7.2 search of paths. The 0.7.3 release includes new iterations able to extend the path A-B-C-D-CSW, if F is an effective target. If yes, the smart reading requirement is provided, and there is no other work to do. If no, a new negative-right path from A to F is necessary to inform the user this path is forbidden. Another case to consider is when the view contains A, C and F. If the path A-B-C-D-CSW-E-F is the result of a context switch by CSW from the properties of the node A, this new view does not find the path A-B-C-D-CSW-E-F. It should even have no path (C, F) at all. On the other hand, the path A-B-C-D-CSW-E-F exists. Beyond offering a 'smart' reading, whatever the nodes the user chooses to put into a view, the graph of access paths must deliver the same level of data. This enforces, in this example, to add a path to the view with A, C and F, as a displayed link from A to F. To provide this feature, the release 0.7.3 adds to the class CompoundRighsFactoryImpl the 4 methods withOtherDLinksFromContextSwitch(), addContextSwitchLinksToHiddenCompoundEpRights(), addFinalContextSwitchLinksToHiddenCompoundEpRights() and addCommentedContextSwitchLinks() (see the case 5 at the section 'SIX EXAMPLES OF EVOLUTION'). It is recommanded to read carefully their documentation to work with.
Another context to consider is the streams between the ACS (new in 0.7.3). The aim is to be able to restore the AG context from an ACS 'M' when the path leaves 'M' to go through another ACS 'K' then returns into 'M' or enters into a third ACS. A simple example is a path from an ACS Ubuntu which goes accross a child ACS MySQL and ends with an Ubuntu resource. The rights on this last resource depends on the restored AG context of the last Ubuntu node which is just before the entering into the child ACS MySQL. If the AccessControlLink has activated one of the types Bridge, AclEntry, negative AclEntry, Linked Privilege, negative Linked Privilege, Alias or Spread, then the AG context into another ACS may be changed by a ContextSwitch (there, from the ACS MySQL), or by reading the value of the key DisplayableLinkUtilities.PREVIOUS_ACS_AG_CONTEXTS into the properties map of the displayable link. This second feature is the work of the method DisplayableLinkUtilities.getSecondEndAGcontext(), for instance when the path leaves the child ACS MySQL and returns on the ACS Ubuntu.
At the end of the access paths search for an EPR view, each pair of ACSObjects in the view may have a list of DisplayableLinks. The method RightsFactory_Facade.getEffectiveRightsForPair() is responsible to get the effective rights and the final state of comments for the 'See why' text. The algorithm is summarized hereinafter:
into an iteration on each DisplayableLinkImpl (or 'dLink'):
call to FactoryUtilities.isActivePath() for the dLink, where each internal AccessControLink (or 'acLink') is parsed:
an acLink is activated if AccessControlLinkImpl.isTrueForOnePseudoStructuralLinkType() validates it, or if the acLink second end is a VirtualFolder
AccessControlLinkImpl.getFilteredRights() returns four Set of StringRights, with the immutable positive ones at the index 0, the immutable negative ones at the index 1, the other positive rights at 2, and the last other negative ones at 3,
UtilityImpl.subtractNegativeNotRemovingInOneACS() is called if necessary, to subtract the negative rights for the immutable rights, then for the mutable rights,
after the merging of all the rights, UtilityImpl.withExecuteRight() is called to desactivate the acLink if the result is 'false',
if any internal acLink of the dLink is desactivated, FactoryUtilities.isActivePath() returns false; otherwise, it returns true even if the data exchange reduced maximal rights produce an incompatibility among the rights,
if FactoryUtilities.isActivePath() returns false, there is no result from the dLink if it is not simple, or if isTrueForOneNegativeLinkType() returns false on its single AccessControlLinkImpl,
otherwise, DisplayableLinkUtilities.getEffectiveRightsAndCommentOnRights() provides the effective data about dLink, using an algorithm close to FactoryUtilities.isActivePath(), but only for the last AccessControlLink; there is in addition a call to UtilityImpl.selectHeaders() which filters the lower rights, to DisplayableLinkUtilities.mergeDataExchangeCommentsInLastLink() which parses the reduced maximal rights for the data exchanges, and to LinkRight.detectDataExchangeRightsConstraints() which reduces the effective rights from the DATA_EXCHANGE constraints, if necessary,
DisplayableLinkUtilities.getEffectiveRightsAndCommentOnRights() returns 2 strings, where the first one is for the returned value by this method, and the second one contains the description for the 'See why' text,
there is no result from the dLink if FactoryUtilities.withSomeAccess() returns 'false' for the first string from DisplayableLinkUtilities.getEffectiveRightsAndCommentOnRights(), and if AccessControlLinkImpl.isTrueForOnePseudoStructuralLinkType() returns 'false' for the last acLink of dLink or if DisplayableLinkUtilities.getEffectiveRightsAndCommentOnRights() has returned 2 empty sets for the rights and the comments,
for the 'See why' text, from the second string from DisplayableLinkUtilities.getEffectiveRightsAndCommentOnRights(), the synthesis of the rights for dLink is put into the last AccessControlLink, by the way of the SPREAD comment of the last AccessControlLink,
the effective rights of the dLink last link are added to one of the two sets 'l_result_' (if dLink has an actor as intermediate node) or 'l_noActorResult_',
after the iteration on all the dLinks of the pair (_so, _tg), call to UtilityImpl.selectHeaders() for the instance properties 'l_result_' and 'l_noActorResult_',
for each right of the final result, call to FactoryUtilities.getRightAcronym() to get the correct representation of the right, and adding of '<via>' before the rights from the instance property 'l_result_'.
During the search, it is common to find some paths of 7 nodes or more. A search of all the paths from an Ubuntu UserID to an Ubuntu Resource accross the child ACS MySQL may deliver 80 different access paths. To make the 'See why' texts lighter, after the search of all the paths, the paths are parsed to count the number of paths having any sequence of 3 nodes A-B-C, whatever the values of A, B and C. If there are numerous paths having this sequence A-B-C, some of them are not described into the 'See why' text. This means the 'See why' text is not complete in such a case. The total number of paths is given at the beginning of the paths. There is also a note at the end of the 'See why' text to enumerate the filtered sequences A-B-C.
The performance of the access paths search is slower for the version 0.7.3. This is mainly due to the new concepts of ExchangePoint and ContextSwitch. They increases the number of cases to consider. There is also the complete handling of the soft aliases. The AcsAddon MySQL is much slower because its AcsAddon method for NodeRights.selectAddonHiddenNodeForFirstEndAndGroupIDMember() parses all the resources to find the aliases and their soft references as Ubuntu roots.
After this package document, studying the class ThreeNodesRightsFactoryImpl is a good start for understanding the logic of the access path search. This class is devoted to find the paths of exactly 3 nodes. The method gWork.ThreeNodesRightsFactoryImpl.detectOneHiddenNodeCompoundRights() detects more than 100 different kinds of paths, through the call to varied methods of the same class. Because ThreeNodesRightsFactoryImpl is quite complex, it is recommanded to start with the followings:
the class CNot.AccessControlLink for the relation types between two nodes in an access path,
the class CNot.DisplayableLinkImpl for the general modeling of an access path, including its global properties,
the method gWork.AgoRightsFactoryImpl.detectAGRights() for the basics about the path search for the Account and Group relations,
the method gWork.RightsFactory_Facade.getEffectiveRightsForPair() for delivering the data to display in the view and the 'See Why' text, after a full path search.
THE THREAD MANAGEMEMENT PATTERN ON gWork
The thread management pattern and the event management pattern for the views are described in the documentation of Gui2.GraphicViewBaseListenerImpl. With the view threads, the first aim is to update quickly the access paths of a view when a property has changed in a view node. This is why it is done outside the event dispatch thread and the main thread, in a pool of worker threads managed by Gui2.ViewModel. The worker threads work also at the view creation or opening. The maximal number of worker threads for the views is set to 3 by code in Gui2.ViewModel. For the generic gWork package, the main principles are the followings:
the classes xxxRightsFactoryImpl provides the most general algorithms. Each view has an instance of each of these classes, to perform an efficient multi-threading without thread collision. These classes are stateless.
this is also true for the classes DisplayableLinkUtilities, FactoryUtilities and gBase.UtilityImpl. They implements core algorithms for the access paths search. The 0.6 version solution, that is to use synchronized methods, get too much loss of time.
A node in a view, and a found node that should be an intermediate node in an effective access path, use a dedicated NodeRights instance and a dedicated LinkRights instance for each view it belongs to. Each instance of NodeRights and LinkRights is called by only one thread. The two effective classes may be subclasses from the AcsAddon of the node, or may be the NodeRightsImpl and LinkRightsImpl classes of this generic gWork package. These classes are stateless.
A node may be in several DisplayableLinkImpls of the same view, but only one time in a given DisplayableLinkImpl. An ACS may have several ACSObjects in a view. At the analysis level, it needs only one LinkRights instance for each view, but RightsMediatorImpl handles one instance per node.
The RightsMediatorImpl instance of the view manages the associations between (1) a node and its NodeRights instance, from its AcsAddon or from this generic gWork, (2) a node and its LinkRights instance, from its AcsAddon or from this generic gWork, (3) a view and the xxxRightsFactoryImpl, yyyUtilities and UtilityImpl instances for this view, always from this generic gWork.
From the point of view of RightsFactory_Facade, there are small differences in the use of worker threads for updating a view. For a gBase.EPRViewInBase or a NoThanViewInBase class, RightsFactory_Facade is called in a worker thread, as it is describes later. For a gBase.SketchViewInBase class, RightsFactory_Facade is called in the main thread by the method ViewInBase_Facade.populateSketchView().
THE ACSADDON PATTERN ON gWork
With the AcsAddon pattern, the path search algorithms are designed in an object-oriented structure. This pattern allows to make use of the generic nature of the gBase concepts in the algorithms. It is possible to add an additional processing, or to alter the generic algorithms, by the mean of new AcsAddons gWork packages.
The use of the gWork package in the AcsAddon pattern is presented hereinafter:
The AcsAddon pattern allows a programmer to add more easily to Access Road some Java classes for implementing new gBase and/or new gWork functions. This pattern may be used when these packages do not provide the required functions for the simulation of a given software.
The first solution to study is always to code the creation of a new type of ACS in gDMak.ActionNewACSyst and gWork.AcsFactory, using the current gBase and gWork packages. Otherwise, a first alternative is to modify directly the code of these generic packages. This is more powerful, but may become much more complex, like for adding the Alias relation. Furthermore, the compatibility with Access Road becomes then an important issue, since this compatibility may be lost, and it requires in all cases acareful testing.
On the other hand, with the AcsAddon pattern, the interfaces of the new classes with the Access Road generic packages are designed to be stable and relatively small. With the AcsAddon pattern, only the new functions are coded, and most of the current Access Road code is reused. For these reasons, the resulting code is much more easy to test and maintain. An AcsAddon may be based on another AcsAddon.
Each AcsAddon has specific Java packages. They are named from the AcsAddon name, like 'ARoad0.AcsAddon.Accbee.Ubuntu.gBase' for the gBase package for the AcsAddon Ubuntu from the editor ACCBEE. The AcsAddon may include a gBase package, with its gBaseBeanInfo and its gBaseInterface packages. It always includes a gWork package, with at least an ARoad0.Pattern.AcsFactoryForAcsAddon implementation to create the ACS of the AcsAdddon. In the simplest case, an AcsAddon contains only one AcsFactoryForAcsAddon and one subclass of any generic gBase or gWork class, to change the generic behavior of the class. Ubuntu may be studied to understand a complex use of the AcsAddon pattern.
The core algorithms are the larger part of the generic gWork package code. 5 generic xxxRightsFactoryImpl classes contain these algorithms. They are based on the semantic of the gBase classes, and contain functional programming that works for all the ACSs, from an AcsAddon or not, using the generic gBaseInterface interfaces. These classes are so independent to the AcsAddon packages.
The utility methods are in the classes DisplayableLinkUtilities, RightsFactoryUtilities and UtilityImpl. They cannot be overridden by the AcsAddons. Their behavior cannot be changed. The classes CNot.AccessControlLinkImpl and CNot.DisplayableLinkImpl cannot be overridden by the AcsAddons. However, an AcsAddon may add and read some proper GLOBAL comments to an AccessControlLinkImpl, and also some additional properties to a DisplayableLinkImpl.
The NodeRights and LinkRights generic methods are called by the core methods to process each node and the paths. They are the main way to change the generic behavior for a given AcsAddon. They handle the generic and the specific properties of an ACSObject and its environment, like the generic properties of a Resource and the specific properties of a ResourceUbuntu in the Ubuntu AcsAddon. LinkRights.addAndRemoveDisplayableLinks() is an important example, since it is the unique way to add or to reject a new DisplayableLinkImpl in the map of the view. As another example, in ThreeNodesRightsFactoryImpl, the 3-nodes path groupidmember/is_member/group/is_member/group is analyzed. It uses for this only the core algorithms, some utility methods and generic methods like NodeRights.selectHiddenDirectGroupIDForGroupIDMember(). These generic methods work for all the ACS. They are always called by the core algorithms. An AcsAddon may choose to override them. This would allow for instance to handle differently the rights inheritance into the 'ThroughNodesTree' methods.
There are also in NodeRights and LinkRights some AcsAddon methods, with the name pattern detectAddon... or selectAddon... The core algorithms include the test of the getXXXAddonYYY methods for the node, and if one method returns true, the relevant AcsAddon method is called. In ThreeNodesRightsFactoryImpl, to take account of the AcsAddon additions in the GroupIDMember relations, the AcsAddon method selectAddonLastViewNodeAfterGroupIDMember() is called on the central group of the 3-nodes path, to detect any path like groupidmember/is_member/group/any AcsAddon relation/group. These AcsAddon methods are empty in the NodeRightsImpl and LinkRightsImpl classes. All the getXXXAddonYYY methods return false. They may be overridden in the subclasses to write a code that calls some specialized AcsAddon methods.
The specialized methods of an AcsAddon for searching the access paths are in a NodeRightsImpl or LinkRightsImpl subclass. They are called by an AcsAddon method. In ThreeNodesRightsFactoryImpl, a developer may add a specific SPREAD relation between two GroupIDs in its AcsAddon. He will do it simply by overriding the AcsAddon method selectAddonLastViewNodeAfterGroupIDMember() in his subclass of NodeRightsImpl. selectAddonLastViewNodeAfterGroupIDMember() calls there a specialized method addAliasGroupRelationToDisplayableLink(). In such a case, there is no name pattern for the specialized methods. They use the generic properties of a node and its environment. Of course, they also handle the specific properties of the AcsAddon node. To define the specific relations between the nodes, the AcsAddon use the standard types of CNot.AccessControlLink, but it may add new comments to well explain the link in the 'See why' text. The MySQL AcsAddon uses an ALIAS link to describe the link between a proxy account and its proxied account.
Since an AcsAddon may be based on another AcsAddon, a subclass may be extended from another NodeRightsImpl or LinkRightsImpl subclass.
In an AcsAddon, to process the AclEntry or Privilege inherited rights, it is necessary to code how the Directory or VirtualFolder subclass updates the inherited rights in its children, since the generic algorithms do not provide this feature. Sometimes, it is also necessary to code the LinkRightsImpl subclass. An example is for overriding some of the six 'ThroughNodesTree' methods which implement the default rights inheritance algorithms.
A typical application of the AcsAddon pattern is for adding a new search algorithm. It may be necessary to handle the typed privileges differently. In that case, a LinkRightsImpl subclass is necessary to override the four 'PrivilegeForType' methods.
Of course, changing a new property in an ACS addon may produce some changes in the access paths. The interface methods ACSObjectAddon.getAddonInnerPropertiesToListen() and AcsAddon.getAddonParentPropertiesToListen() describe the AcsAddon property change events. A view has to listen them if it contains a node from such an AcsAddon.
This AcsAddon pattern has been described for the case where a dedicated NodeRights is associated to a view node. Since varied relations are always internal to an ACS, it is possible to use the NodeRights of another node from the same ACS. This is done for instance to find the UserID and the GroupID under which an Actor starts its running.
A typical application of the AcsAddon pattern is the method getSecondEndAGcontext() in the generic class DisplayableLinkUtilities. This important method updates and returns the current Account/Groups context of the second end of a DisplayableLinkImpl. For the access paths into a given ACS, the method LinkRights.setNextNodeAGrunningContextInOneACS() is responsible to change or not the current AG context. To illustrate the role af an AcsAddon, let's take an exemple. When an AcsAddon Ubuntu UserID 'U' has some generic Account/Group rights, or even some specific AGO 'Other' rights on an Actor 'A', the generic search extends the displayable link ended by the UserID 'U' by the node 'A', with an OWNER, CONTAIN or GLOBAL relation between them. The generic implementation LinkRightsImpl.setNextNodeAGrunningContextInOneACS(), for the OWNER type, does not change the AG context. In most of the cases, this is correct to transfer it to the next possible nodes. But not if the Actor 'A' is setuid, in other words, if it changes its own AG context when it is executed. This is why it is necessary to overridde LinkRightsImpl by a class LinkRightsUbuntuImpl offering a specific setNextNodeAGrunningContextInOneACS() method to the AcsAddon Ubuntu.
The main limitation of the AcsAddon pattern is to not allow any evolution of the GUI for a given ACS addon. The Sketcher is not able to display the main EligibleParties having inherited AclEntry or Privilege on a Resource, since the selection of the objects to associate to a Resource, in the Sketcher, is done in a generic class, outside the AcsAddon pattern.
THE AUTOMATED NON-REGRESSION TESTS
The automated non-regression tests are based on the free software TestNG. The gBase packages include numerous integrity controls. The main data is visible in the beamer. So, the greater risks of errors are in the gWork packages. The access paths search cannot include too much controls, since it has to be fast. This is why the non-regression tests are about the access paths search in the gWork packages. The main testing method is based on an EPRViewInBase. It is presented there as an exemple. The packages gBase, CNot and gWork are covered. This is the signature of this main testing method:
public void testEPRViewAccessPaths(
EPRViewInBaseImpl _view,
Map.<ImmutableName, List<Integer>> _m_path_sizes,
Map<ImmutableName, Set<StringRight>> _m_effective_rights,
Map<ImmutableName, String> _m_strengthen_types,
Map<ImmutableName, Map<String, String> _m_properties,
int _testDeep)
This method tests the access paths of an EPRViewInBase in face of 5 possible criteria. The deep of the test is set by the last argument _testDeep. Each pair of view objects is tested through the call to RightsFactory_Facade.detectEPRRights(). The second and third criteria are derived from the code of GraphicEPRView.buildUpArrowsAndRights(). For each pair of nodes, the test arguments are applied. They are presented hereinafter:
with '_m_path_sizes', the number of access paths and their sizes are the two first mandatory criterion to check.
the optional final effective rights of each pair of nodes is the third criterion. These rights are returned by RightsFactory_Facade.getFirstShapeEffectiveRights().
the optional strengthen types of the last AccessControlLink from the first DisplayableLinkImpl of each pair are the fourth criterion. They are get from AccessControlLinkImpl.getActivatedStrengthenTypes().
the optional properties of the last DisplayableLinkImpl for each nodes pair are the fifth criterion. The last link is used because it is often the longer path. All the properties are tested. They are get from DisplayableLinkImpl.getProperties().
'_testDeep' has to be below '2' to test only _m_path_sizes, '2' to test only _m_path_sizes and _m_rights, '3' to test all the arguments excepted the last one, or '4' to test all the arguments.
To create a GraphicEPRView, the code is derived from ActionOpenGraphicView.openViewInGui() and GraphicEPRView.initialize() without handling the GUI packages.
SIX EXAMPLES OF EVOLUTION
1 - It is quite easy to add a new access path search in the generic gWork package, if the responsibility of each class and the code patterns are well understood. The VirtualFolder type EP_VFolder was, in a first non-published version, reserved for having only EligibleParties as members. It appears this was too restricted, for example to model the MySQL views where table columns (as Resources) and stored functions (as Actors) may be members. To add Resources in EP_VFolder VirtualFolder, the controls in the method addEorBaseObject() was simply changed in the class VirtualFolderImpl of the gBase package. There was no change to do in the GUI packages. For the access path search, the single evolution was in the processing of a VirtualFolder member being the source of a relation, as an EligibleParty, since there is now the case where the member is not an EligibleParty. This was analyzed in two methods of the core algorithms: ThreeNodesRightsFactoryImpl.selectOneHiddenNodePathsForVirtualFolder(), and CompoundRightsFactoryImpl.detectHiddenCompoundEpRightsForDLinks(). Handling Resources in EP_VFolder VirtualFolders needs to add no more than 10 lines of code in these two generic gWork methods.
2 - By the way of its method getL_EntryEPtoSwitchTo(), the ContextSwitch models an ACS entry point (new in 0.7.3). It provides the selection of an own UserID for a given AG context from the previous nodes in the access path. In the generic gWork, a ContextSwitch is processed as any Actor. To add this search in gWork for the 2-nodes and 3-nodes paths, the method NodeRights.selectDirectOwnerContainGlobalForActorAsEP() becomes selectDirectHiddenLinksForActorAsEP() with a DisplayableLinkImpl as new argument. Like selectDirectHiddenLinksForActorAsEP() but for the paths having more than 3 nodes, CompoundRightsFactoryImpl.detectHiddenCompoundEpRightsForDLinks() calls DisplayableLinkUtilities.getSecondEndAGcontext() to get the applicable UserID/GroupIDs of a given ContextSwitch. This is provided by the way of a simple change of LinkRights.setNextNodeAGrunningContextBetweenTwoACS(). This new feature implies less than 30 lines of code in gWork. The hard work has been, in a previous step, to define the method LinkRights.setNextNodeAGrunningContextBetweenTwoACS() as a new mandatory way to handle the access paths accross two ACS.
3 - This section describes how the ExchangePoint interface is taken in account into the access paths search by the gWork packages (new in 0.7.3). The search detects the paths from an Actor master program to its ExchangePoints, and the single path from an ExchangePoint to its Actor master program. The method NodeRight.selectDirectHiddenLinksForActorAsEP() returns some ACSObjects that are the ExchangePoints or an Actor master program of the Actor argument, when they are in the view. For the hidden objects of a view, ThreeNodesRightsFactoryImpl and CompoundRightsFactoryImpl.detectHiddenCompoundEpRightsForDLinks() call NodeRight.selectDirectHiddenLinksToActorAsEP() and selectForGroupIDMemberItsHiddenActorsWithNextLinks() to get the same result. ThreeNodesRightsFactoryImpl.addPathsFromActorDataExchangeActor() is created to complement the search. Each time an ExchangePoint is found as a possible extension of an access path in AclRightsFactoryImpl, PrivilegeRigthsFactoryImpl or CompoundRightsFactoryImpl, of through a NodeRigths method, it is necessary to call NodeRights.withAccessToLastExchangePoint() to verify if the ExchangePoint ACS allows to communicate with it. Each time a relation like ExchangePoint/acl or bridge or privilege/ExchangePoint is found in AclRightsFactoryImpl, PrivilegeRigthsFactoryImpl or CompoundRightsFactoryImpl, of through a NodeRigths method, it is necessary to call DisplayableLinkUtilities.addDataExchangeCommentsToLastLink() to verify if the reduced maximal rights of the two ExchangePoint are compatible and if the previous node is allowed as sender. At the end of the search, to filter the resulting rights of an access path from the reduced maximal rights of each inner ExchangePoint, the final loop of CompoundRightsFactoryImpl.detectHiddenCompoundEpRightsForDLinks() is changed to call the new method LinkRights.detectExchangeRightLimitationsInAllLinks(). This new method is also called by ThreeNodesRightsFactoryImpl.detectOneHiddenNodeCompoundRights(). Another feature is to forbid into the access paths any sequence of nodes like ExchangePoint/acl or bridge or privilege/ExchangePoint/acl or bridge or privilege/ExchangePoint. The ExchangePoints are modeled as the communication interfaces of their master programs. All the methods of NodeRights and LinkRights may be overridden in an AcsAddon. The management of ExchangePoint in Access Road 0.7.3 produces less than 300 lines of new code in the generic gWork, but these changes are done in numerous classes.
4 - An example of gWork evolution is for the Alias relation. Two ACSObjects may be associated by an alias relation, where the first object is called a reference and the second object is called its alias. This is used in the MySQL AcsAddon. After the adding of the CAliasImpl class in the gBase package, there are numerous new access paths to detect in the gWork package. Considering only the 3-nodes paths, many new paths become possible because alias is applicable to all the ACSObjects. 41 new paths appear in the ThreeNodesRightsFactoryImpl class, like the path 'ep virtual folder/virtual member/actor/alias/reference'. Three methods are added in CompoundRightsFactoryImpl to detect the direct and indirect Alias paths. The searching for large paths has to be completed. The overall effort to handle the Alias relation in the generic gWork package has produced about 130 lines of new code in CompoundRightsFactoryImpl, and the same number of lines in ThreeNodesRightsFactoryImpl. In this specific example, the ratio 'number of new paths'/'number of new lines of code' is quite good, but there is a large number of new test cases for validating the code.
5 - CompoundRightsFactoryImpl is the most complex Access Road class. With the release 0.7.3, the complexity has increased to deal with ContextSwitch. The new method detectHiddenCompoundEpRightsForDLinks() defines the effective applicable rights through all the access paths containing more than 3 nodes. After its first call to find the classical paths, RightsFactory_Facade.detectEPRRights() may invoke this method several times for exploring the ContextSwitch abilities. A ContextSwitch may select, as next path node, a GroupIDMember which depends on the properties of the first end of the path. There are 2 main cases:
(a) if there is an entry or exit CSW in the view, all the paths ended to it with an executing right on this CSW may be extended to reach other view nodes;
(b) if there is a hidden entry or exit CSW in a path between two view nodes, with an executing right on it, if the first end of the path in the view is a proxy actor, and if there is at least a path with an executing right on it, all the paths ended with the first end may be extended through the hidden CSW to reach other view nodes.
At its first call, the new argument '_l_DisplayableLinksToExtend' in CompoundRightsFactoryImpl.detectHiddenCompoundEpRightsForDLinks() is null. After this first call, this argument contains the DisplayableLinkImpls to extend, following the two cases above. This argument is then used to reset most of the instance properties, at the beginning of detectHiddenCompoundEpRightsForDLinks(). This behavior requires, in the release 0.7.3, to split the previous method detectHiddenCompoundEpRights() in two parts, where detectHiddenCompoundEpRightsForDLinks() makes most of the work. The new argument '_l_DisplayableLinksToExtend' is defined first by the new method withOtherDLinksFromContextSwitch(), then by addCommentedContextSwitchLinks(). It contains non-simple DisplayableLinkImpls ended by a view node. The second new argument '_m_viewNodesToPassThrough' is also defined first by the new method withOtherDLinksFromContextSwitch(), then by addCommentedContextSwitchLinks(). Its role is to define the indirect paths to explore in the next extensions by detectHiddenCompoundEpRightsForDLinks(), for each link into '_l_DisplayableLinksToExtend'. A link A-B into '_l_DisplayableLinksToExtend' is extended only if the extending node C provides a new Account/Group context, in other words, a context that is not produced by the simple link B-C. The resulting links are returned by CompoundRightsFactoryImpl.detectHiddenCompoundEpRightsForDLinks() to the caller RightsFactory_Facade.detectEPRRights(). It invokes the new method addCommentedContextSwitchLinks(), which is responsible to update the map of the final access paths:
If there is an extended link, and if all the indirect paths in '_m_viewNodesToPassThrough' have not been still parsed for this link, some new undetected ContextSwitch abilities remain to explore, and these links are returned by addCommentedContextSwitchLinks().
If there is an extended link, and if all the indirect paths in '_m_viewNodesToPassThrough' have been parsed, this link is added to the final result.
If there is no extended link, this should mean the indirect path is not workable, then it is necessary to add a negative-right link to the final result, for avoiding a wrong reading of the diagram by the user.
RightsFactory_Facade.detectEPRRights() iterates to invoke CompoundRightsFactoryImpl.detectHiddenCompoundEpRightsForDLinks() again. The method addCommentedContextSwitchLinks() updates 2 of its arguments, and it returns a list in a loop with the most complex method of the program. This is far from the classical Java style of code, where the arguments are never updated. Such a functionnal-style of code provides a much clearer and more compact code, but it is harder to test. To handle these complex ContextSwitch abilities, the overall effort in the generic gWork package has required about 2000 lines of new code in the class CompoundRightsFactoryImpl. This feature may have a major impact on the performance of the access paths search, if numerous iterations are required. There is also a great number of test cases for validating the new code.
6 - An example of use for the AcsAddon framework is the simulation of high-level requirements as roles. The Workbench software handles roles to design the MySQL Server rights. The Access Road generic algorithms deliver an efficient simulation of roles, like for the RBAC application. But it is not suffisant to simulate the roles in the MySQL Workbench, where the ACL of the role has to be copied, in the ACS of the targetted MySQL Server, as the ACL of each user that is member of the role. The MySQL Workbench software is simulated as a subACS into the MySQL Server ACS. In the gBase package of the ACS addon for MySQL, a subclass of GroupIDMySQLImpl, called RoleMySQLImpl, models the Workbench role. It creates and updates each ACL of user from the role ACL. The RoleMySQLImpl BeanInfo displays the role ACL in the beamer as 'high-level requirements', so they cannot be seen as an effective ACL for the access paths. To get this behavior, in the gWork package of the ACS addon for MySQL, the class NodeRightsMySQLImpl has a method detectL_aclEntryRights which returns no right for all the ACL of a Workbench role. That's all. The AcsAddon pattern allows, with about 100 simple lines of code, to define, implement and explain the concept of high-level requirements for the Workbench roles. This feature is not implemented yet, while the class RoleMySQLImpl is ready to use.
THE LIMITATIONS OF gWork
The main limits in the performance of the access paths search, in the 0.7 version, are presented hereinafter:
During a search, a DisplayableLinkImpl may have to be removed after its insertion in the final result. The reason is the filtering of access paths to apply some priority rules among the AG, PRI, ACL or the BDG rights. Some of these priority rules may be from an AcsAddon, through the call to a method LinkRights.detectAddonPriorityInXXX(). These methods have the property to detect a priority link which enforces to remove one or several longer links in the final result. The inverse is not true, since a long link cannot produce, by its existence, the removing of a shorter link.
Ease-of-use: medium. The core algorithms are complex, and it is necessary to well understand the CNot and gBase packages before any change. Nevertheless, the AcsAddon pattern provides powerful and simple means to add new simulations, even if all the code in this package is not well understood.
Reliability: medium. There are no known bugs.