/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.brixcms.plugin.menu;
import org.apache.wicket.model.IDetachable;
import org.brixcms.jcr.api.JcrNodeIterator;
import org.brixcms.jcr.wrapper.BrixNode;
import org.brixcms.web.reference.Reference;
import java.util.ArrayList;
import java.util.List;
public class Menu implements IDetachable {
private RootEntry root = new RootEntry();
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public RootEntry getRoot() {
return root;
}
public void detach() {
root.detach();
}
public void load(BrixNode node) {
loadName(node);
loadMenu(node);
}
public void loadName(BrixNode node) {
if (node.hasProperty("name")) {
setName(node.getProperty("name").getString());
}
}
public void loadMenu(BrixNode node) {
root = new RootEntry();
if (node.hasNode("menu")) {
loadEntry((BrixNode) node.getNode("menu"), root);
}
}
private void loadEntry(BrixNode node, Entry entry) {
JcrNodeIterator i = node.getNodes("child");
while (i.hasNext()) {
BrixNode child = (BrixNode) i.nextNode();
ChildEntry e = new ChildEntry(entry);
loadChildEntry(child, e);
loadEntry(child, e);
entry.getChildren().add(e);
}
}
private void loadChildEntry(BrixNode node, ChildEntry entry) {
if (node.hasProperty("title")) {
entry.setTitle(node.getProperty("title").getString());
}
entry.setReference(Reference.load(node, "reference"));
if (node.hasProperty("cssClass")) {
entry.setCssClass(node.getProperty("cssClass").getString());
}
if (node.hasProperty("labelOrCode")) {
entry.setLabelOrCode(node.getProperty("labelOrCode").getString());
}
if (node.hasProperty("menuType") && ChildEntry.MenuType.valueOf(node.getProperty("menuType").getString()) != null) {
entry.setMenuType(ChildEntry.MenuType.valueOf(node.getProperty("menuType").getString()));
}
}
public void save(BrixNode node) {
if (!node.isNodeType("mix:referenceable")) {
node.addMixin("mix:referenceable");
}
node.setProperty("name", getName());
if (node.hasNode("menu")) {
node.getNode("menu").remove();
}
BrixNode menu = (BrixNode) node.addNode("menu", "nt:unstructured");
saveEntry(menu, getRoot());
}
private void saveEntry(BrixNode node, Entry entry) {
if (entry instanceof ChildEntry) {
ChildEntry childEntry = (ChildEntry) entry;
node.setProperty("title", childEntry.getTitle());
node.setProperty("cssClass", childEntry.getCssClass());
node.setProperty("menuType", childEntry.getMenuType().toString());
node.setProperty("labelOrCode", childEntry.getLabelOrCode());
if (childEntry.getReference() != null) {
childEntry.getReference().save(node, "reference");
}
}
for (Entry e : entry.getChildren()) {
BrixNode child = (BrixNode) node.addNode("child");
saveEntry(child, e);
}
}
public static class Entry implements IDetachable {
private final Entry parent;
public Entry(Entry parent) {
this.parent = parent;
}
public Entry getParent() {
return parent;
}
private final List<ChildEntry> children = new ArrayList<ChildEntry>();
public List<ChildEntry> getChildren() {
return children;
}
public void detach() {
for (ChildEntry entry : children) {
entry.detach();
}
}
}
public static class RootEntry extends Entry {
public RootEntry() {
super(null);
}
@Override
public String toString() {
return "Menu Root";
}
public String getTitle() {
return "Menu Root";
}
public Reference getReference() {
return null;
}
public String getCssClass() {
return null;
}
}
public static class ChildEntry extends Entry {
public ChildEntry(Entry parent) {
super(parent);
}
public static enum MenuType {
REFERENCE, LABEL, CODE
}
private MenuType menuType;
public MenuType getMenuType() {
if (menuType == null) {
menuType = MenuType.REFERENCE;
}
return menuType;
}
public void setMenuType(MenuType menuType) {
this.menuType = menuType;
}
private String title;
private Reference reference;
private String labelOrCode;
private String cssClass;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Reference getReference() {
return reference;
}
public void setReference(Reference reference) {
this.reference = reference;
}
public String getLabelOrCode() {
return labelOrCode;
}
public void setLabelOrCode(String labelOrCode) {
this.labelOrCode = labelOrCode;
}
public String getCssClass() {
return cssClass;
}
public void setCssClass(String cssClass) {
this.cssClass = cssClass;
}
@Override
public void detach() {
super.detach();
if (reference != null) {
reference.detach();
}
}
@Override
public String toString() {
return getTitle();
}
}
}