/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.celements.menu;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.annotation.Requirement;
import org.xwiki.context.Execution;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.query.Query;
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryManager;
import com.celements.menu.access.IMenuAccessServiceRole;
import com.celements.web.service.IWebUtilsService;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.objects.BaseObject;
@Component
public class MenuService implements IMenuService {
private static Log LOGGER = LogFactory.getFactory().getInstance(MenuService.class);
@Requirement
IWebUtilsService webUtilsService;
@Requirement
QueryManager queryManager;
@Requirement
IMenuAccessServiceRole accessService;
@Requirement
Execution execution;
private XWikiContext getContext() {
return (XWikiContext) execution.getContext().getProperty("xwikicontext");
}
public List<BaseObject> getMenuHeaders() {
LOGGER.trace("getMenuHeaders_internal start");
TreeMap<Integer, BaseObject> menuHeadersMap = new TreeMap<Integer, BaseObject>();
addMenuHeaders(menuHeadersMap);
getContext().setDatabase("celements2web");
addMenuHeaders(menuHeadersMap);
getContext().setDatabase(getContext().getOriginalDatabase());
ArrayList<BaseObject> resultList = new ArrayList<BaseObject>();
resultList.addAll(menuHeadersMap.values());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("getMenuHeaders_internal returning: " + Arrays.deepToString(
resultList.toArray()));
}
LOGGER.debug("getMenuHeaders_internal end");
return resultList;
}
void addMenuHeaders(SortedMap<Integer, BaseObject> menuHeadersMap) {
try {
List<String> result = queryManager.createQuery(getHeadersXWQL(), Query.XWQL).execute();
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("addMenuHeaders received for " + getContext().getDatabase() + ": "
+ Arrays.deepToString(result.toArray()));
}
for (String fullName : new HashSet<String>(result)) {
DocumentReference menuBarDocRef = webUtilsService.resolveDocumentReference(fullName);
if (accessService.hasview(menuBarDocRef)) {
List<BaseObject> headerObjList = getContext().getWiki().getDocument(menuBarDocRef,
getContext()).getXObjects(getMenuBarHeaderClassRef(
menuBarDocRef.getWikiReference().getName()));
LOGGER.trace("addMenuHeaders: hasview for ["
+ webUtilsService.getRefDefaultSerializer().serialize(menuBarDocRef)
+ "] adding items [" + ((headerObjList != null) ? headerObjList.size() : "null")
+ "].");
if (headerObjList != null) {
for (BaseObject obj : headerObjList) {
if (obj != null) {
menuHeadersMap.put(obj.getIntValue("pos"), obj);
}
}
}
} else {
LOGGER.trace("addMenuHeaders: NO hasview for ["
+ webUtilsService.getRefDefaultSerializer().serialize(menuBarDocRef) + "].");
}
}
} catch (XWikiException exp) {
LOGGER.error("Failed to addMenuHeaders.", exp);
} catch (QueryException queryExp) {
LOGGER.error("Failed to execute query in addMenuHeaders.", queryExp);
}
}
public DocumentReference getMenuBarHeaderClassRef() {
return getMenuBarHeaderClassRef(getContext().getDatabase());
}
public DocumentReference getMenuBarHeaderClassRef(String database) {
return new DocumentReference(database, "Celements", "MenuBarHeaderItemClass");
}
public DocumentReference getMenuBarSubItemClassRef() {
return getMenuBarSubItemClassRef(getContext().getDatabase());
}
public DocumentReference getMenuBarSubItemClassRef(String database) {
return new DocumentReference(database, "Celements", "MenuBarSubItemClass");
}
String getHeadersXWQL() {
return "from doc.object(Celements.MenuBarHeaderItemClass) as mHeader"
+ " group by doc.fullName";
}
public List<BaseObject> getSubMenuItems(Integer headerId) {
TreeMap<Integer, BaseObject> menuItemsMap = new TreeMap<Integer, BaseObject>();
addMenuItems(menuItemsMap, headerId);
getContext().setDatabase("celements2web");
addMenuItems(menuItemsMap, headerId);
getContext().setDatabase(getContext().getOriginalDatabase());
ArrayList<BaseObject> resultList = new ArrayList<BaseObject>();
resultList.addAll(menuItemsMap.values());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("getSubMenuItems_internal returning: " + Arrays.deepToString(
resultList.toArray()));
}
LOGGER.debug("getSubMenuItems_internal end");
return resultList;
}
private void addMenuItems(TreeMap<Integer, BaseObject> menuItemsMap, Integer headerId) {
try {
List<Object[]> result = queryManager.createQuery(getSubItemsXWQL(), Query.XWQL).bindValue(
"headerId", headerId).execute();
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("addMenuItems received for " + getContext().getDatabase() + ": "
+ Arrays.deepToString(result.toArray()));
}
for (Object[] resultObj : result) {
String fullName = resultObj[0].toString();
int objectNr = Integer.parseInt(resultObj[1].toString());
DocumentReference menuBarDocRef = webUtilsService.resolveDocumentReference(fullName);
BaseObject obj = getContext().getWiki().getDocument(menuBarDocRef, getContext()).getXObject(
getMenuBarSubItemClassRef(menuBarDocRef.getWikiReference().getName()), objectNr);
menuItemsMap.put(obj.getIntValue("itempos"), obj);
}
} catch (XWikiException e) {
LOGGER.error(e);
} catch (QueryException e) {
LOGGER.error(e);
}
}
private String getSubItemsXWQL() {
return "select doc.fullName, subItem.number"
+ " from Document as doc, doc.object(Celements.MenuBarSubItemClass) as subItem"
+ " where subItem.header_id = :headerId";
}
}