/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.wgpublisher.webtml;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.WGArea;
import de.innovationgate.webgate.api.WGContent;
import de.innovationgate.webgate.api.WGContentList;
import de.innovationgate.webgate.api.WGContentNavigator;
import de.innovationgate.webgate.api.WGResultSet;
import de.innovationgate.webgate.api.WGStructEntryList;
import de.innovationgate.wgpublisher.lang.WebTMLLanguageChooser;
import de.innovationgate.wgpublisher.webtml.utils.ResultIterator;
import de.innovationgate.wgpublisher.webtml.utils.ResultSetTagStatus;
import de.innovationgate.wgpublisher.webtml.utils.TMLContext;
import de.innovationgate.wgpublisher.webtml.utils.TMLException;
public class Navigator extends ForEach {
public static final String TAGINFO_RESULTCOUNT = "resultcount";
public static final String TAGINFO_CONTENTLIST = "contentlist";
private String maxLevel;
private String allareas;
private String alllanguages;
private String role;
private String allowdefaultlang;
private String exclude;
public static class Status extends ForEach.Status implements ResultSetTagStatus {
private int iMaxLevel;
private WGContentList contentList;
protected String navType;
@Override
public Object getTagInfo(String name) throws WGAPIException {
if (name.equals(TAGINFO_RESULTCOUNT)) {
return new Integer(this.contentList.size());
}
else if (name.equals(TAGINFO_CONTENTLIST)) {
return this.createContextList(this.contentList);
}
return super.getTagInfo(name);
}
public TMLContext[] createContextList(WGContentList contentList) throws WGAPIException {
TMLContext[] contextList = new TMLContext[contentList.size()];
for (int idx = 0; idx < contentList.size(); idx++) {
contextList[idx] = tmlContext.getTMLContextForDocument((WGContent) contentList.get(idx));
}
return contextList;
}
@Override
public void initAttributeDelegates(Base tag) {
super.initAttributeDelegates(tag);
Navigator navTag = (Navigator) tag;
this.forEachType = "content";
this.navType = navTag.getType();
}
public String getResultLanguage() {
return MULTILANGUAGE_RESULT;
}
public ResultIterator getResultIterator() throws TMLException {
if (contentList != null) {
return new ResultIterator((List) contentList);
}
else {
throw new TMLException("Tag has no result list", true);
}
}
public int results() {
return contentList.size();
}
public void addResultSet(WGResultSet resultSet, String language) {}
}
@Override
public BaseTagStatus createTagStatus() {
Status status = new Status();
return status;
}
public void tmlStartTag() throws TMLException, WGAPIException {
Status status = (Status) getStatus();
WGContentNavigator navigator;
if (this.allowdefaultlang != null) {
addWarning("Attribute \"allowdefaultlang\" is deprecated and inoperable since OpenWGA 5.1");
}
WGContent relContent = this.getTMLContext().content();
// IF the relContent is a dummy, use the first released content of this database
if (relContent.isDummy()) {
relContent = relContent.getDatabase().getFirstReleasedContent((String) getTMLContext().meta("language"), true);
if (relContent == null) {
addWarning("No content in context and cannot find released content of language " + getTMLContext().meta("language") + " in the current database", true);
return;
}
}
String theRole = this.getRole();
String type = status.navType;
if (type.equals("children")) {
navigator = createContentNavigator(theRole, WGContent.DISPLAYTYPE_NAVIGATOR);
WGStructEntryList childEntries = relContent.getStructEntry().getChildEntries();
status.contentList = WGContentList.create(navigator.collectRelevantContents(childEntries));
}
else if (type.equals("siblings")) {
navigator = createContentNavigator(theRole, WGContent.DISPLAYTYPE_NAVIGATOR);
WGStructEntryList siblingEntries = relContent.getStructEntry().getSiblingEntries();
status.contentList = WGContentList.create(navigator.collectRelevantContents(siblingEntries));
}
else if (type.equals("parent") || type.equals("parents")) {
navigator = createContentNavigator(theRole, WGContent.DISPLAYTYPE_NAVIGATOR);
WGStructEntryList parentEntries = relContent.getStructEntry().getParentEntry().getSiblingEntries();
status.contentList = WGContentList.create(navigator.collectRelevantContents(parentEntries));
}
else if (type.equals("path")) {
navigator = createContentNavigator(theRole, WGContent.DISPLAYTYPE_NAVIGATOR);
status.contentList = this.getPathListFor(relContent, navigator);
}
else if (type.equals("sitemap")) {
navigator = createContentNavigator(theRole, WGContent.DISPLAYTYPE_SITEMAP);
status.contentList = this.getSitemapListFor(relContent, navigator, this.stringToBoolean(this.getAllareas()));
}
else if (type.equals("languages")) {
navigator = createContentNavigator(theRole, WGContent.DISPLAYTYPE_NONE);
status.contentList = this.getLanguagesListFor(relContent, navigator, this.stringToBoolean(this.getAlllanguages()));
}
else if (type.equals("areas")) {
navigator = createContentNavigator(theRole, WGContent.DISPLAYTYPE_NAVIGATOR);
status.contentList = this.getAreasListFor(relContent, navigator);
}
else if (type.equals("versions")) {
status.contentList = relContent.getStructEntry().getAllContent(true);
}
else {
throw new TMLException("Unknown navigator type: " + type, true);
}
String exclude = getExclude();
if (exclude != null) {
TMLContext excludeContext = getTMLContext().context(exclude, false);
if (excludeContext != null) {
status.contentList.remove(excludeContext.content());
}
else {
addWarning("Unresolvable exclude context: " + exclude, false);
}
}
status.forEachType = "content";
super.tmlStartTag();
}
private WGContentNavigator createContentNavigator(String theRole, String defaultRole) throws WGAPIException {
Status status = (Status) getStatus();
WGContentNavigator navigator = new WGContentNavigator((theRole != null ? theRole : defaultRole), new WebTMLLanguageChooser(getTMLContext().db(), getTMLContext()));
// Set if this navigator should only return published documents
if (!isCollectionsShowReleasedOnly()) {
status.onlyPublished = false;
}
navigator.setOnlyPublished(status.onlyPublished);
return navigator;
}
private WGContentList getAreasListFor(WGContent content, WGContentNavigator navigator) throws WGAPIException {
java.util.ArrayList contents = new java.util.ArrayList();
Iterator areas = content.getDatabase().getAreas().values().iterator();
WGArea area;
while (areas.hasNext()) {
area = (WGArea) areas.next();
content = navigator.getRootContent(area);
if (content != null) {
contents.add(content);
}
}
return WGContentList.create(contents);
}
private WGContentList getPathListFor(WGContent content, WGContentNavigator navigator) throws WGAPIException {
java.util.ArrayList contents = new java.util.ArrayList();
while (content != null) {
if (content.isVisibleFor(navigator.getDisplayType())) { // Necessary for first content
contents.add(content);
}
content = navigator.getParentContent(content);
}
java.util.Collections.reverse(contents);
return WGContentList.create(contents);
}
private WGContentList getSitemapListFor(WGContent content, WGContentNavigator navigator, boolean allAreas) throws WGAPIException {
Status status = (Status) getStatus();
if (this.getMaxlevel() != null) {
try {
status.iMaxLevel = Integer.parseInt(this.getMaxlevel());
}
catch (NumberFormatException exc) {
this.addWarning("Could not parse max level: " + this.getMaxlevel());
status.iMaxLevel = Integer.MAX_VALUE;
}
}
else {
status.iMaxLevel = Integer.MAX_VALUE;
}
java.util.ArrayList contents = new java.util.ArrayList();
if (allAreas == false) {
WGContent rootContent;
if (content.isDummy() || !content.hasCompleteRelationships()) {
rootContent = content.getDatabase().getFirstReleasedContent(content.getLanguage().getName(), true);
}
else {
rootContent = navigator.getRootContent(content.getStructEntry().getArea());
}
if (rootContent == null) {
return new WGContentList();
}
Iterator rootSiblings = navigator.collectRelevantContents(rootContent.getStructEntry().getSiblingEntries()).iterator();
while (rootSiblings.hasNext()) {
WGContent siblingContent = (WGContent) rootSiblings.next();
this.retrieveHierarchy(siblingContent, contents, navigator, 1);
}
}
else {
Iterator areas = content.getDatabase().getAreas().iterator();
WGArea area;
while (areas.hasNext()) {
area = (WGArea) areas.next();
if (area.isSystemArea()) {
continue;
}
WGContent rootContent = navigator.getRootContent(area);
if (rootContent == null) {
continue;
}
Iterator rootSiblings = navigator.collectRelevantContents(rootContent.getStructEntry().getSiblingEntries()).iterator();
while (rootSiblings.hasNext()) {
WGContent siblingContent = (WGContent) rootSiblings.next();
this.retrieveHierarchy(siblingContent, contents, navigator, 1);
}
}
}
return WGContentList.create(contents);
}
private WGContentList getLanguagesListFor(WGContent relContent, WGContentNavigator navigator, boolean allLanguages) throws WGAPIException {
return navigator.getLanguagesContent(relContent, allLanguages);
}
private void retrieveHierarchy(WGContent content, ArrayList contents, WGContentNavigator navigator, int level) throws WGAPIException {
Status status = (Status) getStatus();
contents.add(content);
if (level < status.iMaxLevel) {
WGContent childContent = navigator.getChildContent(content, 0, WGContent.SEARCHORDER_ASCENDING);
while (childContent != null) {
this.retrieveHierarchy(childContent, contents, navigator, level + 1);
childContent = navigator.getNextSibling(childContent);
}
}
}
/**
* Gets the maxLevel
* @return Returns a String
*/
public String getMaxlevel() {
return this.getTagAttributeValue("maxlevel", maxLevel, null);
}
/**
* Sets the maxLevel
* @param maxLevel The maxLevel to set
*/
public void setMaxlevel(String maxLevel) {
this.maxLevel = maxLevel;
}
/**
* Gets the allareas
* @return Returns a String
*/
public String getAllareas() {
return this.getTagAttributeValue("allareas", allareas, "false");
}
/**
* Sets the allareas
* @param allareas The allareas to set
*/
public void setAllareas(String allareas) {
this.allareas = allareas;
}
/**
* Gets the alllanguages
* @return Returns a String
*/
public String getAlllanguages() {
return this.getTagAttributeValue("alllanguages", alllanguages, "false");
}
/**
* Sets the alllanguages
* @param alllanguages The alllanguages to set
*/
public void setAlllanguages(String alllanguages) {
this.alllanguages = alllanguages;
}
/**
* Returns the role.
* @return String
*/
public String getRole() {
return this.getTagAttributeValue("role", role, null);
}
/**
* Sets the role.
* @param role The role to set
*/
public void setRole(String role) {
this.role = role;
}
/**
* @return Returns the allowdefaultlang.
*/
public String getAllowdefaultlang() {
return getTagAttributeValue("allowdefaultlang", allowdefaultlang, "false");
}
/**
* @param allowdefaultlang The allowdefaultlang to set.
*/
public void setAllowdefaultlang(String allowdefaultlang) {
this.allowdefaultlang = allowdefaultlang;
}
public String getExclude() {
return getTagAttributeValue("exclude", exclude, null);
}
public void setExclude(String includecurrent) {
this.exclude = includecurrent;
}
}