Standard Actions Specification

Author: Nathan Fiedler

The standard actions consist of delete, cut, copy, paste, and drag-n-drop. This specification seeks to describe how these features will perform on the columns view of the schema editor.

Phased Implementation

Because of the depth of features possible with copy/paste and drag/drop, the design and implementation will be taken in a phased approach. The most basic features will be implemented first, while the complex features, such as refactoring, will come at a later date.

Phase 1

In Phase 1 of the standard actions implementation, the copy and paste, as well as drag and drop, will operate in much the same way as the similar features in NetBeans. That is, copying and pasting components will not involve any adjustments to references or alterations to the data in any way. It is up to the user to ensure that the schema is still valid before it is employed.

Supported Features

  • Copy and paste will simply make a copy of the component in the new location (no refactoring, no references)
  • Pasting components with a namespace may elide the namespace if it is not needed
  • Drag and drop, like copy and paste, will be implemented in a similar fashion, with the same limitations
  • Modifying a component's visibility, such that a global component can become a local component, and vice versa

Phase 2

Phase 2 of the implementation will add refactoring capabilities to take care of some of the more mundane work on behalf of the user.

Supported Features

  • Pasting a component where it cannot immediately be added will result in finding the first matching child component that can accept the paste.
  • Pasting a component as a reference will be possible for those types of components that can have references
  • Pasting a component as a reference from another schema will create an import and the reference to the source component
  • Safely moving a component via refactoring

Delete

The delete feature was implemented earlier in the development cycle and has been functional for some time. At first it was labelled as "Remove" and would only allow deletion of components that were not used elsewhere. In May 2006, the RemoveAction was renamed to SafelyDeleteAction and the standard NetBeans DeleteAction was added to the schema component nodes. This allows the user to forcefully delete nearly anything, without regards to references to that component. On the other hand, if the user wants to remove a component only after ensuring it is not used elsewhere, they can select the "Safe Delete" action.

Cut, Copy, and Paste

The cut operation will need to be handled in the same fashion as delete, since the user could cut a component from the document and not paste it back again. This is effectively the same as a delete, and since we cannot know what the user will do, it should be handled defensively. Components that are not being used elsewhere in the same document, can be cut, just as they can be deleted.

The copy operation, on the other hand, is unrestricted in that any component can be copied and pasted, regardless of whether it is being used elsewhere.

Is the following necessary? If the name of the original component is identical to that of another component in the destination container, it must be changed to one that is unique. This is similar to the behavior of copy/paste within Java projects, in which a source file is renamed to avoid collision with existing files.

Drag and Drop

Drag and drop can be treated differently from cut and paste, since we know for certain the affected components will not be discarded. That is, dragging and dropping a component is a single operation, rather than two distinct events as in cut/paste — no components can be lost.

Where drag/drop is particularly useful is in changing the order of elements in a sequence. Whereas paste can only be applied on the parent component, the drop can be performed between components. That is, if an element is copied to the clipboard, then pasted, it must be pasted onto a component that can contain it (e.g. a sequence). The drag and drop interface allows the user to insert a component between other components, thus allowing the order of elements in a sequence to be changed, for example.

The condition of maintaining unique component names within a container, mentioned in the copy and paste section above, holds for drag and drop. That is, dropping a component into a container that contains a component with the same name as that which is being dropped will result in the dropped component being renamed to avoid collision.

Global to Local

The table below describes what kinds of components can go where when moving from a global context to a local one.

Component Kind Destination Kind Result
Attribute Attribute Group Move, unless referenced.
Attribute Complex Type Move, unless referenced.
Attribute Group Attribute Group A reference is created.
Attribute Group Complex Type A reference is created.
Attribute Group Redefine Move, unless referenced.
Complex Type Element Move, unless referenced.
Complex Type Redefine Move, unless referenced.
Simple Type Attribute Move, unless referenced.
Simple Type Element Move, unless referenced.
Simple Type List Move, unless referenced.
Simple Type Redefine Move, unless referenced.
Simple Type Restriction Move, unless referenced.
Simple Type Union Move, unless referenced.

Local to Global

The table below describes what kinds of components can be moved from a local context to the global (child of schema root component).

Component Kind Parent Kind Exceptions
Attribute Attribute Group  
Attribute Complex Type  
Attribute Group Attribute Group Invalid case
Attribute Group Complex Type Invalid case
Attribute Group Redefine  
Complex Type Element  
Complex Type Redefine  
Simple Type Attribute  
Simple Type Element  
Simple Type List  
Simple Type Redefine  
Simple Type Restriction  
Simple Type Union  

Unless noted otherwise, the components can be moved from a local context to the root schema component. If the component does not have a name, it will be given one (e.g. "attribute0").

Implementation Details

Determining Ability to Paste

To determine if it is possible to paste a particular type of component into another component, the SchemaComponent class provides a method called canPaste() that takes a SchemaComponent parameter and returns true indicating that the component can contain that child. In the case of CategoryNode this is trivial since the childType field gives us the type of components being shown in that category.

Visibility Changes

When a component is being copied to a destination context that is different from its origin (global vs. local), it will be necessary to create a new component of the appropriate type, then copy the attributes from the original component to its clone. The model handles this already.

Copying Components

The Component class provides a copy() method that creates a deep clone of a component for a new parent. This is used for the copy operation.

Format (i.e. DataFlavor)

By default, the AbstractNode implementation copies itself to the clipboard and handles the paste via a PasteType implementation. Since this is the most straightforward means of supporting copy and paste, as well as drag and drop, this will be the format used for the clipboard transferables.

Aside from overriding createPasteTypes() in our Node subclasses, there is a ComponentPasteType utility class that does the work of creating the PasteType implementations for our nodes.

Operations

The Category node class will need to override canCopy() to return false, as it makes little sense to copy an entire category to the clipboard. Likewise, need to override createPasteTypes() to ensure that only nodes of the same type as what the category contains are permitted to be pasted.

The SchemaComponentNode class will override canCopy() and canCut() to return true, since basically any node can be copied and cut. It also overrides the method createPasteTypes() to ensure that only nodes representing components that can be contained in the node's component are able to be pasted to the node.

To allow pasting a component to a logical parent, which may not be the structural parent, the PasteType will employ FindContainerVisitor to find the first reasonable parent component for the paste.

Drag and Drop

NetBeans drag and drop support is a little strange. Most of the drag-n-drop specific code is suppressed and it is all handled via copy/paste and the org.openide.nodes.Index cookie. For instance, the index parameter is always -1 when Node.getDropType() is called, so ordering the nodes by that method is useless (this problem is caused by the DragDropUtilities class). Likewise, there is no use in overriding drag() since it is apparently not called (again, DragDropUtilities is the culprit, in that it invokes clipboardCut() for drag-move).

To allow reordering the nodes, you must implement the org.openide.nodes.Index cookie. This is most easily done by implementing it on a subclass of org.openide.nodes.Children, which provides an implementation of a couple of the Index methods already.

Project Features

About this Project

XML was started in November 2009, is owned by dstrupl, and has 58 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20160708.bf2ac18). © 2014, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
 
 
Close
loading
Please Confirm
Close