package nota.oxygen.dtbook;
import nota.oxygen.common.BaseAuthorOperation;
import nota.oxygen.common.Utils;
import ro.sync.ecss.extensions.api.ArgumentDescriptor;
import ro.sync.ecss.extensions.api.ArgumentsMap;
import ro.sync.ecss.extensions.api.AuthorConstants;
import ro.sync.ecss.extensions.api.AuthorDocumentController;
import ro.sync.ecss.extensions.api.AuthorOperationException;
import ro.sync.ecss.extensions.api.node.AuthorElement;
import ro.sync.ecss.extensions.api.node.AuthorNode;
/**
* @author OHA
*
*/
public class RemoveLevelHeadingOperation extends BaseAuthorOperation {
private static String ARG_NS = "namespace";
private static String ARG_BLOCK_REPLACEMENT_NAME = "block-replacement-name";
private static String ARG_GENERIC_LEVEL_TAG = "generic-level-tag";
private static String ARG_GENERIC_HEADING_TAG = "generic-heading-tag";
private static String ARG_FIXED_LEVEL_TAGS = "fixed-level-tags";
private static String ARG_FIXED_HEADING_TAGS = "fixed-heading-tags";
@Override
public ArgumentDescriptor[] getArguments() {
return new ArgumentDescriptor[] {
new ArgumentDescriptor(ARG_NS, ArgumentDescriptor.TYPE_STRING, "Namespace of level container and heading elements"),
new ArgumentDescriptor(ARG_BLOCK_REPLACEMENT_NAME, ArgumentDescriptor.TYPE_STRING, "Name of the block element to replace the heading element with"),
new ArgumentDescriptor(ARG_GENERIC_LEVEL_TAG, ArgumentDescriptor.TYPE_STRING, "Name of the generic level container element"),
new ArgumentDescriptor(ARG_GENERIC_HEADING_TAG, ArgumentDescriptor.TYPE_STRING, "Name of the generic level heading element"),
new ArgumentDescriptor(ARG_FIXED_LEVEL_TAGS, ArgumentDescriptor.TYPE_STRING, "Names of the fixed-depth level container elements, separated by |"),
new ArgumentDescriptor(ARG_FIXED_HEADING_TAGS, ArgumentDescriptor.TYPE_STRING, "Name of the fixed-depth level heading elements, separated by |")};
}
String ns;
String blockReplacementName;
String genericLevelTag;
String genericHeadingTag;
String[] fixedLevelTags;
String[] fixedHeadingTags;
@Override
protected void parseArguments(ArgumentsMap args)
throws IllegalArgumentException {
ns = (String)args.getArgumentValue(ARG_NS);
if (ns==null) ns = "";
blockReplacementName = (String)args.getArgumentValue(ARG_BLOCK_REPLACEMENT_NAME);
genericLevelTag = (String)args.getArgumentValue(ARG_GENERIC_LEVEL_TAG);
if (genericLevelTag==null) genericLevelTag = "";
genericHeadingTag = (String)args.getArgumentValue(ARG_GENERIC_HEADING_TAG);
if (genericHeadingTag==null) genericHeadingTag = "";
fixedLevelTags = ((String)args.getArgumentValue(ARG_FIXED_LEVEL_TAGS)).split("\\|");
fixedHeadingTags = ((String)args.getArgumentValue(ARG_FIXED_HEADING_TAGS)).split("\\|");
}
protected boolean isHeadingElement(AuthorElement elem) {
if (elem==null) return false;
if (elem.getNamespace().equals(ns)) {
String ln = elem.getLocalName();
if (ln.equals(genericHeadingTag)) return true;
for (int i=0; i<fixedHeadingTags.length; i++) {
if (ln.equals(fixedHeadingTags[i])) return true;
}
}
return false;
}
protected boolean isLevelElement(AuthorElement elem) {
if (elem==null) return false;
if (elem.getNamespace().equals(ns)) {
if (elem.getLocalName().equals(genericLevelTag)) return true;
for (int i=0; i<fixedLevelTags.length; i++) {
if (elem.getLocalName().equals(fixedLevelTags[i])) return true;
}
}
return false;
}
@Override
public String getDescription() {
return "Merges the level in which the current element is heading with it's surrounding levels";
}
protected int getLastChildOrSelfEndOffset(AuthorElement elem) {
if (elem!=null) return elem.getEndOffset();
AuthorNode lastChild = Utils.getLastChild(elem);
if (lastChild!=null) return lastChild.getEndOffset();
return 0;
}
@Override
protected void doOperation() throws AuthorOperationException {
try {
if (fixedLevelTags==null) throw new AuthorOperationException("Nanes of fixed level container elements are missing");
if (fixedHeadingTags==null) throw new AuthorOperationException("Nanes of fixed heading elements are missing");
if (fixedLevelTags.length!=fixedHeadingTags.length) {
//showMessage("fixed levels: "+flt+" fixed headings: "+fht);
throw new AuthorOperationException(
"Different number names of elements for fixed level containers and headings are different"
+"- counts are "+fixedLevelTags.length+" and "+fixedHeadingTags.length+" respectively");
}
AuthorDocumentController docCtrl = getAuthorAccess().getDocumentController();
int startSel = getSelectionStart();
AuthorElement firstAthElem = (AuthorElement)docCtrl.getNodeAtOffset(startSel);
if (!isHeadingElement(firstAthElem)) {
showMessage("Current element is not a level heading");
return;
}
AuthorElement parentLevel = (AuthorElement)firstAthElem.getParent();
if (!isLevelElement(parentLevel)) {
showMessage("Current heading is unexpectedly not the child of a level element (parent is a "+parentLevel.getLocalName()+")");
return;
}
AuthorElement previousSibling = Utils.getPreviousSibling(parentLevel);
AuthorElement grandParent = (AuthorElement)parentLevel.getParent();
if (isLevelElement(previousSibling)) {
docCtrl.renameElement(firstAthElem, blockReplacementName);
docCtrl.removeAttribute("depth", firstAthElem);
int pos = getLastChildOrSelfEndOffset(previousSibling);
docCtrl.insertXMLFragment(serializeChildren(parentLevel), previousSibling, AuthorConstants.POSITION_INSIDE_LAST);
docCtrl.deleteNode(parentLevel);
getAuthorAccess().getEditorAccess().setCaretPosition(pos+1);
}
else if (isLevelElement(grandParent)) {
int pos = parentLevel.getStartOffset();
docCtrl.renameElement(firstAthElem, blockReplacementName);
docCtrl.removeAttribute("depth", firstAthElem);
docCtrl.insertXMLFragment(serializeChildren(parentLevel), parentLevel, AuthorConstants.POSITION_AFTER);
docCtrl.deleteNode(parentLevel);
getAuthorAccess().getEditorAccess().setCaretPosition(pos+1);
}
else {
showMessage(
"The level of which the current element is heading is the first at level 1 in "+grandParent.getLocalName()
+" and therefore cannot be removed");
return;
}
}
catch (Exception e) {
if (e instanceof AuthorOperationException) {
throw (AuthorOperationException)e;
}
else {
throw new AuthorOperationException(
"Unexpected "+e.getClass().getName()+" occured: "+e.getMessage(),
e);
}
}
}
}