System and method having programmable containers with functionality for managing objects5682532Abstract An improved storage mechanism is provided. In a preferred embodiment of the present invention, a container is used for storing objects, links to objects, and other containers. The container of the preferred embodiment is programmable so that the methods of the container are replaceable and the functionality of the container is extendible through the use of a command unit. Claims We claim: Description TECHNICAL FIELD
CODE TABLE NO. 1
______________________________________
interface IContainerItem: IUnknown {
Virtual HRESULT delete() = 0;
Virtual HRESULT move () = 0;
Virtual HRESULT copy () = 0;
Virtual HRESULT invoke(ULONG propid,
VARIANT * ppropvalue, ULONG propaction) = 0;
VARIANT Hidden;
VARIANT Archive;
VARIANT AccessControlList;
VARIANT *Application;
VARIANT Classifications;
VARIANT Comments;
VARIANT LastAccessDate;
VARIANT LastAccessedBy;
VARIANT LastModifiedBy;
VARIANT LastModifiedDate;
VARIANT Container;
VARIANT Moniker;
VARIANT ReadOnly;
VARIANT Name;
VARIANT Size;
VARIANT Object;
VARIANT Unread;
______________________________________
The Delete method deletes the corresponding item from the container and frees up the associated storage. To perform this functionality, the Delete method invokes the Delete method of the IShellContainer interface (described below), passing a moniker associated with the item. The moniker of an item is a reference to the item and is stored as a property (the "Moniker" property) in the IContainerItem interface. Monikers are described in detail in U.S. patent application Ser. No. 08/088,724, entitled "Method and System for Naming and Binding Objects," which is hereby incorporated by reference. The Delete method of the IShellContainer interface frees up the associated storage. The Move method prepares the corresponding item for being moved. That is, the move method places the IContainerItem interface for the item onto the clipboard. The Copy method preferably has the same functionality as the Move method. The Invoke method of the IContainerItem interface is used to retrieve and set the values of the properties in the IContainerItem interface. The invoke method has three parameters: propid, ppropvalue and propaction. The propid parameter to the invoke method indicates which property is to be accessed. The ppropvalue parameter is a pointer to a memory location returning the value of a retrieved property or passing the value of a property to be set. The propaction parameter indicates whether to retrieve the value of the indicated property or whether to set the value of the indicated property. The properties of the IContainerItem Interface are tagged as being type VARIANT. The VARIANT type is used to overcome limitations in strongly-typed programming languages. A strongly-typed language typically binds a parameter to a type at compile time. Thus, a parameter can only be of one type. The VARIANT type overcomes this limitation by being defined as a union of all types of variables, thereby making the specification of any one type acceptable to the programming language. The Hidden property is a Boolean variable indicating whether the item is hidden. A hidden item cannot be accessed or viewed by a user interface. The Archive property interface is a Boolean variable indicating whether the item has been modified since the item was last archived. One skilled in the art would recognize that the Archive property is similar to a "dirty bit." By using the Archive property, an archiving utility can determine whether to archive the item. The AccessControlList property is a list containing access privileges to the item. The AccessControlList preferably lists the users allowed to access the item. The Application property is a reference to the application program which can manipulate the data of the item. For example, if the item were a word processing document, the application program indicated by the Application property would be the specific word processor used for editing the item. The Classifications property contains the class identification of the item, that is, the type of item (e.g., MSSpreadsheet). The Comments property is a character string containing various comments that are associated with the item as input from a user through the UI 510. The LastAccessDate property is a character string containing the date of the last time that the item was accessed. The LastAccessedBy property is a character string containing the name of the last user or application program to access the item. The LastModifiedBy property is a character string containing the name of the last user or application to modify the item. The LastModifiedDate property is a character string containing the date the item was last modified. The Container property contains a reference to the IUnknown interface of the container from which the item was accessed. The Moniker property contains a reference to a linked object. If the item is not a linked object, then the reference is NULL. The ReadOnly property is a Boolean variable indicating whether the item is only available for read access. The Name property contains the name of the item in a human-readable form. The Size property contains the size of the item in bytes. The Object property contains a reference to the IUnknown interface of the object when the object is instantiated. The Unread property contains whether an item has been opened through the UI 510. The property is used, for example, to determine if a mail message has been read. As previously stated, a container provides three interfaces through which a UI can manipulate the container and the contents of the container. The three interfaces are: the IShellContainer interface, the IQueryContainer interface, and the IContainerAutomation interface. The IShellContainer interface provides the ability to manipulate the items contained within the container. The methods contained in the IShellContainer interface provide for such functionality as deleting items, creating items, moving items, copying items, linking items, and accessing the data of items. In addition, the methods of the IShellContainer interface generate events. An event is a message generated by the container to apprise another entity that a specific event occurred. An entity that wishes to be apprised of an event registers itself with the container. The entity preferably registers a "callback routine" with the container. When the event occurs, the container invokes the callback routine to apprise the container. These callback routines provide extensions to the container. Alternatively, entities can be apprised through standard interprocess communication mechanisms. The IShellContainer interface and the prototypes for the event callback routines are shown in Code Table No. 2.
CODE TABLE NO. 2
______________________________________
Events
RequestItemAdd(PCONTAINERITEM pContainerItem,
BOOL *cancel);
RequestItemRemove(PCONTAINERITEM pContainerItem,
BOOL *cancel);
DoItemAdd(PCONTAINERITEM pContainerItem, BOOL
*enabledefault);
DoItemRemove(PCONTAINERITEM pContainerItem, BOOL
*enabledefault);
AfterItemAdd(PCONTAINERITEM pContainerItem);
AfterItemRemove(PCONTAINERITEM pContainerItem);
Interface IShellContainer:IUnknown {
virtual HRESULT MoveHere(VARIANT *punk, ULONG
*pcMonikers, IMONIKER ***pppmnk) = 0;
virtual HRESULT CopyHere(VARIANT *punk, ULONG
*pcMonikers, IMONIKER ***pppmnk) = 0;
virtual HRESULT LinkHere(IUNKNOWN *punk, ULONG
*pcMonikers, IMONIKER ***pppmnk) = 0;
virtual HRESULT GetDataObject(const ULONG cMonikers,
IMONIKER **ppmnk, IDATAOBJECT
**ppDataObject) = 0;
virtual HRESULT Delete(IMONIKER **ppmnk, ULONG
cMonikers) = 0;
virtual HRESULT Create(REFCLSID rclsid, const
LPWSTR pwszName, SECURITY.sub.-- DESCRIPTOR
*psd, IMONIKER **ppmnk, UNKNOWN
**ppunk) = 0;
}
______________________________________
Events are associated with the adding and removing of items from a container. The events allow the entity that is apprised of an event to perform pre-event and post-event processing, cancel the event, and suppress the default container functionality. A container generates the RequestItemAdd event (invokes the callback routine) when an item is attempted to be added to the container. The RequestItemAdd callback has two parameters: the pContainerItem parameter and the cancel parameter. The pContainerItem parameter is a reference to the IContainerItem interface for the item to be added. The cancel parameter is set by the callback routine and indicates whether the container should proceed with adding the item. A container generates the RequestItemRemove event when the container is requested to delete an item. The parameters for the RequestItemRemove event are similar to those described for the RequestItemAdd event. A container generates the DoItemAdd event right before an item is added to the container. The DoItemAdd event has two parameters: the pContainerItem parameter and the enabledefault parameter. The pContainerItem parameter is a reference to the IContainerItem interface for the item being added. The enabledefault parameter is a Boolean variable which is set by the callback routine and indicates whether the container should perform its default add functionality. A container generates a DoItemRemove event just prior to deleting or removing an item from the container. The DoItemRemove event has analogous parameters as the DoItemAdd event. A container generates the AfterItemAdd event immediately after an item has been added to the container. The AfterItemAdd event has one parameter, which is a reference to the IContainerItem interface for the item being added. A container generates the AfterItemRemove event immediately after an item has been removed from the container and its parameter is a reference to the item being deleted. The IShellContainer interface has six methods: the MoveHere method, the CopyHere method, the LinkHere method, the GetDataObject method, the Delete method and the Create method. The methods return a return code "HRESULT" to the caller indicating the success or failure of the particular method. The MoveHere method of the IShellContainer interface moves an item into the container. The punk parameter of the MoveHere method is a reference to the IDataObject interface of the item to be moved. The IDataObject interface is an interface used for transferring an item as described in U.S. patent application Ser. No. 08/199,853, entitled "Uniform Data Transfer," which is hereby incorporated by reference. If, however, more than one item is being moved into the container, the punk parameter contains a reference to an IUnknown interface of an object that contains other objects, which is known as a multi-data object. The method can retrieve the references to the objects of the multi-data object by enumerating the objects. By using the punk parameter in this way, a caller can move more than one item at a time. The pcMonikers parameter of the MoveHere method is a return parameter containing a count of the number of items moved into the container. The pppmnk parameter is a triple pointer return parameter referring to the monikers of the items moved into the container. The pppmnk parameter is an optional parameter, thus, if set to NULL, the MoveHere method does not return the monikers to the caller. FIGS. 6A and 6B depict a flow chart of the steps performed by an example implementation of the MoveHere method of the IShellContainer interface. The MoveHere method moves an item from a source container to a destination container and generates the associated events. In step 602, the MoveHere method generates a RequestItemAdd event. Upon generation of the event, the event handler (callback routine) defined by the user is executed and returns. In step 604, the MoveHere method determines the value of the cancel parameter returned from the event handler to determine whether to cancel processing. If the cancel parameter indicates that the MoveHere method should cancel processing, processing ends. However, if the cancel parameter indicates that the MoveHere method should continue processing, processing continues to step 606. In step 606, the MoveHere method prepares the item for movement. That is, in this step the MoveHere method may negotiate using the IDataObject interface over the specific medium used for transfer as well as the format of the data. In step 608, the MoveHere method generates the DoItemAdd event. In step 610, the MoveHere method checks the enabledefault parameter returned from the DoItemAdd event to determine whether to continue processing or whether to return. If the enable default parameter indicates that the default processing should not occur, processing ends. However, if the enabledefault parameter indicates that default processing should occur, processing continues to step 612. In step 612, the MoveHere method moves the item using the methods of the IDataObject interface. That is, the MoveHere method stores the item data within the container. For example, if the container stores each item in a separate file, then the method creates a new file and stores the data in the file. The method also updates internal information to track the contents of the container. In step 614, the MoveHere method generates the AfterItemAdd event. Although the example implementation of the MoveHere method has been described as processing one item, one skilled in the art will appreciate that more than one item can be processed by the MoveHere method. The CopyHere method in the IShellContainer interface copies an item into the container. The punk parameter of the CopyHere method is a reference to the IDataObject interface of the item that is being copied into the container. If, however, more than one item is being copied into the container, the punk parameter contains a reference to an IUnknown interface of a multi-data object. The pcMonikers parameter of the CopyHere method is a return parameter containing a count of the number of items copied into the container. The pppmnk parameter is a triple pointer return parameter referring to the monikers of the items copied into the container. The ppmnk parameter is an optional parameter and, thus, if set to NULL, the CopyHere method does not return the monikers to the caller. The CopyHere method is preferably implemented in a similar fashion to that of the MoveHere method described relative to FIGS. 6A and 6B. The LinkHere method of the IShellContainer interface creates a link object that contains a reference to an object and adds the link object as an item to the container. The punk parameter of the LinkHere method is a reference to the IUnknown interface of the item that is being linked into the container. If, however, more than one item is being linked into the container, the punk parameter contains a reference to an IUnknown interface of a multi-data object. The pcMonikers parameter of the LinkHere method is a return parameter containing a count of the number of items linked into the container. The pppmnk parameter is a triple pointer return parameter referring to the monikers of the items linked into the container. The ppmnk parameter is an optional parameter and, thus, if set to NULL, the LinkHere method does not return the monikers to the caller. The LinkHere method performs similar functionality and generates the same events as the MoveHere method. The LinkHere method, however, instead of creating an object containing data within the container, the LinkHere method creates a link object containing a moniker which refers to the object. The GetDataObject method of the IShellContainer interface provides for returning the IDataObject interface for an item. The cMonikers parameter of the GetDataObject method is the count of the number of items for which the caller would like the IDataObject interfaces. The ppmnk parameter is a pointer to a pointer referring to moniker for the item for which the IDataObject is requested. The ppmnk parameter can also refer to a moniker for a multi-data object through which the method can retrieve a list of monikers. The ppDataObject parameter of the GetDataObject method is a return parameter that contains a pointer to the IDataObject interface of the item or items. After receiving the IDataObject interface of an item, the caller may retrieve the data of the item using the methods in the IDataObject interface. The Delete method in the IShellContainer interface deletes an item from the container. The Delete method has two parameters: ppmnk and cMonikers. The ppmnk parameter is a double pointer to the moniker of an object. The ppmnk parameter may refer to a multi-data object. The cMonikers parameter contains the number of objects referred to by the ppmnk parameter. The Delete method, upon invocation, first generates a RequestItemRemove event. Next, the delete method prepares the item for being deleted which may include accessing the device upon which the item is stored. The delete method then generates a DoItemRemove event, deletes the item and, finally, generates the AfterItemRemove event. After generating both the RequestItemRemove event and the DoItemRemove event, the delete method checks the parameters returned from the events to determine whether to continue processing or to cancel processing. The Create method in the IShellContainer interface creates an item within the container. The rclsid parameter of the Create method is the class identification for the item. For example, if the item were a spreadsheet, the class identification may refer to the spreadsheet program that created the item. The pwszName parameter is a character string containing the name of the item to be created. The psd parameter is an access control list for the item. The ppmnk parameter is a double pointer to a moniker. This parameter is a return parameter that will contain a reference to the item created. The ppunk parameter is a double pointer to the IUnknown interface of the newly created item. The ppunk parameter is an optional parameter, therefore, if the ppunk parameter is set to NULL, the create method does not return the IUnknown interface. However, if the ppunk parameter is non-NULL, the create method will return the IUnknown interface to the newly created item. The create method creates an item, but the item created contains no data. For example, if the contents of the container are files, then the method may create a file. The IQueryContainer interface provides for querying a container to retrieve the contents of the container according to selection criteria. After querying the container, the caller receives the IContainerItem interface for the items matching the selection criteria (e.g., read only items). After receiving the IContainerItem interface for an item, the caller can then directly manipulate the item. The IQueryContainer interface is described in Code Table No. 3.
CODE TABLE NO. 3
______________________________________
Interface IQueryContainer: IUnknown {
virtual IQUERYSPEC *GetQuerySpec() = 0;
virtual IRESULTSET Execute(IQUERYSPEC
pQuerySpec) = 0;
}
______________________________________
The GetQuerySpec method of the IQueryContainer interface returns an IQUERYSPEC interface. The methods of IQUERYSPEC interface are used by a caller to define a query for the container to return a list of items that satisfy a specific selection criteria. The allowable selection criteria include the properties contained in the IContainerItem interface. The query can be based on the properties of the items and specified data of an SQL-type language. Thus, for example, by using the IQUERYSPEC interface, a query can be specified using the Classifications property to retrieve all objects created by a specific word processor. The Execute method returns an IRESULTSET which is a linked list of the IContainerItem interfaces for all items that satisfy the selection criteria. The Execute method of the IQueryContainer interface accepts an IQUERYSPEC interface and executes the query as specified by the IQUERYSPEC interface. The IContainerAutomation interface is layered on top of the IShellContainer interface. That is, the methods of the IContainerAutomation interface invoke the methods of the IShellContainer interface. The IContainerAutomation interface is defined in Code Table No. 4.
CODE TABLE NO. 4
______________________________________
Interface IContainerAutomation: IUnknown {
Virtual MoveHere() = 0;
Virtual CopyHere() = 0;
Virtual LinkHere() = 0;
Virtual DWORD invoke(ULONG propid,
VARIANT * ppropvalue, ULONG propaction) = 0;
VARIANT Contents;
VARIANT ContentTypes;
VARIANT TrackUnread;
}
______________________________________
The MoveHere method of the IContainerAutomation interface moves an item from a source container into the container referenced by the IContainerAutomation interface (the destination container). The MoveHere method has no parameters. The MoveHere method receives the IContainerItem interface for an item to be moved from the clipboard, moves the item into the destination container, and then deletes the item from the source container. FIGS. 7A and 7B depict a flowchart of the steps performed by an example implementation of the MoveHere method of the IContainerAutomation interface. In step 702, the MoveHere method retrieves the IContainerItem interface for an item from the clipboard. In step 704, the MoveHere method obtains the IUnknown interface of the source container from the Container property of the IContainerItem interface. In step 706, the MoveHere method invokes the QueryInterface method of the IUnknown interface of the source container to obtain the IShellContainer interface. In step 708, the MoveHere method obtains the IDataObject interface for the item being moved by invoking the GetDataObject method of the IShellContainer interface with the moniker obtained from the Moniker property of the IContainerItem interface. In step 710, the MoveHere method obtains the IShellContainer interface for the destination container by invoking the QueryInterface method of the IUnknown interface. In step 712, the MoveHere method of the IContainerAutomation interface invokes the MoveHere method of the IShellContainer interface of the destination container to copy the item from the source container to the destination container. In step 714, upon successfully moving the item as indicated by the return code of the MoveHere method of the IShellContainer interface, the MoveHere method of the IContainerAutomation interface invokes the delete method of the IContainerItem interface to delete the item from the source container. The CopyHere method of the IContainerAutomation interface copies an item from a source container into the container referenced by the IContainerAutomation interface (the destination container). The CopyHere method has no parameters. The CopyHere method receives the IContainerItem interface for an item to be copied from the clipboard and copies the item into the destination container. An example implementation of the CopyHere method would be similar to that described relative to the MoveHere method except that the CopyHere method of the IShellContainer interface is invoked instead of the MoveHere method and the item is not deleted from the source container. The LinkHere method of the IContainerAutomation interface adds a link into the container. The LinkHere method receives an IContainerItem interface from the clipboard for an item to be linked into the container and stores a link into the container. The processing performed by the LinkHere method would be similar to that as described for the MoveHere method except that the LinkHere method of the IShellContainer interface is invoked instead of the MoveHere method and the item is not deleted from the source container. The Invoke method of the IContainerAutomation interface is used to retrieve and set the values of the properties in the IContainerAutomation interface. The Invoke method has three parameters: propid, ppropvalue and propaction. The propid parameter of the invoke method indicates which property is to be accessed. The ppropvalue parameter is a pointer to a memory location wherein the invoke method either returns a value of a property or is passed a value of a property. The propaction parameter indicates whether to retrieve the value of the indicated property or whether to set the value of the indicated property. The IContainerAutomation interface provides three properties. The first property is the Contents property which contains a list of the contents of the container. Each entry in the list is a pointer to the IContainerItem interface for the item. The ContentTypes property contains the type of items stored within the container. The TrackUnread property of the IContainerAutomation interface indicates whether the container stores information regarding which items have and have not been read by a user. FIG. 8 depicts a flow chart illustrating steps performed in moving an item from a source container to a destination container by the UI. In step 802, the UI queries the source container for the contents of the source container. The UI performs this query through the IQueryContainer interface. The UI may also determine the Contents by accessing the contents property of the IContainerAutomation interface of the source container. In step 804, the UI selects an item from the list. Since the list of items is actually a list of IContainerItem interfaces for the items, in this step, an IContainerItem interface for the selected item is obtained. In step 806, the UI invokes the Move method of the IContainerItem interface on the selected item. The Move method on the selected item copies the IContainerItem interface to the clipboard. In step 808, the UI retrieves the container for the IContainerAutomation interface of the destination container using the QueryInterface method of the IUnknown interface. In step 810, the UI invokes the MoveHere method of the IContainerAutomation interface of the destination container. The invocation of the MoveHere method moves the item from the source container to the destination container and deletes the item from the source container. The preferred embodiment provides for the replacement of the methods in the IQueryContainer, the IShellContainer and the IContainerAutomation interfaces. That is, a developer wishing to create a container implements one or more methods for the IQueryContainer, the IShellContainer and the IContainerAutomation interfaces to provide specialized processing. Although the MoveHere method of the IShellContainer interface has been described as moving an item into a container, for example, a developer may define additional functionality to be performed by the MoveHere method. Thus, as described above, a developer of a container may implement the MoveHere method of the IShellContainer interface to perform restricted storing, that is, checking the properties of an item to determine whether to allow the item to be moved into the container. The MoveHere method of this example could be implemented by checking the Classifications property of the IContainerItem interface to determine the type of item before actually moving the item into the container. If the type is not appropriate, the MoveHere method would not perform the move. Since the preferred embodiment of the present invention allows for the replacement of the methods contained in the interfaces of the container, the preferred embodiment allows for the customization of containers to specific uses. In regard to the extendibility of the containers of the preferred embodiment, FIG. 9 depicts a diagram of the components used for extending the functionality of a container. The memory 402 contains a command unit 902, the UI 510, and the container 502. The command unit 902 registers the event handlers with the container 502. The event handlers can be procedures defined in a macro language that are invoked in response to the container 502 generating an event. The container 502 receives addresses of the event handlers from the command unit 902 and stores ("registers") the addresses so that when the container generates an event, a corresponding event handler is invoked. For instance, a registered event handler that corresponds to the DoItemAdd event for a container is invoked when the container generates the DoItemAdd event. The interaction between the command unit 902 and the container 502 allows for the extendibility of the container. Although the command unit 902 is shown as being a separate object from the container, the command unit is an aggregate object that contains the container. The aggregation between objects is described in U.S. patent application Ser. No. 08/185,465, entitled "Method and System for Aggregating Objects," which is hereby incorporated by reference. Event processing in the preferred embodiment is performed in two phases: a registration phase and an invocation phase. In the registration phase, a command unit registers the event handlers to be used in the invocation phase. In the invocation phase, events are generated by the methods of the IShellContainer interface and, in response thereto, the corresponding event handlers are invoked. An example event handler in a macro language is provided in Code Table No. 5.
CODE TABLE NO. 5
______________________________________
Sub RequestItemAdd (PCONTAINERITEM pContainerItem,
BOOL cancel)
If pContainerItem->Classifications |=
"MSSpreadsheet" Then
cancel = True
Else
cancel = False
End Sub
______________________________________
The event handier of Code Table No. 5 performs the restricted storing functionality. The event handler corresponds to the RequestItemAdd event, thus, the event handler is invoked every time that an item is attempted to be moved or copied into the container, such as through the MoveHere or CopyHere methods of the IShellContainer interface. This event handler only allows items of type "MSSpreadsheet" into the container. This is done by the event handler checking the Classifications property to determine whether an item to be added to the container is of the correct type. If the item is not an MSSpreadsheet, the cancel parameter is set to true and the method from which the event handler was invoked, is instructed to cancel processing. If, however, the item is of type MSSpreadsheet, the event handler allows the method to add the item into the container. Although the event handlers have been described using a macro language, one skilled in the art will recognize that the present invention can be used to create event handlers using any programming language. In addition, although one example of an event handler is provided, one skilled in the art will recognize that other useful functionality can be provided by event handlers. For example, an event handler can be created to keep various statistical information about the contents of a container and to enforce access control. FIG. 10 depicts a flow chart of the steps performed during the registration phase of event processing by the preferred embodiment. In step 1002, the user defines event handlers using the command unit. The user may define an event handler to be invoked for each event generated by the methods of the IShellContainer interface. In step 1004, the command unit registers the event handlers with the container. The registration of the event handlers with the container is performed as described in U.S. patent application Ser. No. 08/166,976, entitled "Method and System for Dynamically Generating Object Connections," which is hereby incorporated by reference. FIG. 11 depicts a flow chart of the steps performed during the invocation phase of event handling by the preferred embodiment. In step 1102, a method of the IShellContainer interface is invoked on a container; for example, the MoveHere method. In step 1104, during the processing of the MoveHere method of the IShellContainer interface, an event is generated such as the RequestItemAdd event. In step 1106, upon the invocation of an event, the event handier for the event is invoked, such as the event handler described in Code Table No. 5. The event handler performs processing and then returns a value (e.g., cancel) to instruct the method on whether to continue processing or whether to cancel processing. In step 1108, the MoveHere method determines whether to continue processing and either continues processing in step 1110 or cancels processing. In step 1110, if the MoveHere method continues processing, the MoveHere method may generate other events (and execute the corresponding event handlers) and may perform the move of the item unless the executed event handlers override the processing of the MoveHere method. While the present invention has been described with reference to a preferred embodiment thereof, those skilled in the art will know of various changes in form that may be made without departing from the spirit and scope of the claimed invention, as defined in the appended claims.
|
Same subclass Same class Consider this |
||||||||||
