Ergänzungen und Korrekturen für den XMLDeliveryCache

git-svn-id: https://svn.libreccm.org/ccm/trunk@2152 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2013-05-14 13:01:39 +00:00
parent f21e8f8fc1
commit 7d362ba2e6
11 changed files with 484 additions and 295 deletions

View File

@ -1320,6 +1320,11 @@ public class ContentItem extends VersionedACSObject implements CustomCopy {
Assert.isTrue(isLive(), "Attempt to republish non live item " + getOID()); Assert.isTrue(isLive(), "Attempt to republish non live item " + getOID());
//ToDo Remove item from cache
if (CMSConfig.getInstance().getEnableXmlCache()) {
XMLDeliveryCache.getInstance().removeFromCache(getOID());
}
Lifecycle cycle = getLifecycle(); Lifecycle cycle = getLifecycle();
Assert.exists(cycle, Lifecycle.class); Assert.exists(cycle, Lifecycle.class);
//resets lifecycle if opted //resets lifecycle if opted

View File

@ -46,11 +46,11 @@ import java.util.Iterator;
*/ */
class DomainCopier extends DomainService { class DomainCopier extends DomainService {
private static Logger s_log = Logger.getLogger(DomainCopier.class); private static final Logger s_log = Logger.getLogger(DomainCopier.class);
// A map of OID => DomainObject // A map of OID => DomainObject
private final HashMap m_copied; private final HashMap m_copied;
protected final TraversedSet m_traversed; protected final TraversedSet m_traversed;
final Tracer m_trace; protected final Tracer m_trace;
/** /**
* Constructs a new <code>DomainCopier</code> * Constructs a new <code>DomainCopier</code>
@ -127,7 +127,7 @@ class DomainCopier extends DomainService {
} }
} }
protected void copyData(final DomainObject source, DomainObject target) { protected void copyData(final DomainObject source, final DomainObject target) {
final ObjectType type = source.getObjectType(); final ObjectType type = source.getObjectType();
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
@ -295,11 +295,12 @@ class DomainCopier extends DomainService {
} else if (prop.isRequired()) { } else if (prop.isRequired()) {
s_log.debug("The property is a 1..1 association"); s_log.debug("The property is a 1..1 association");
final DataObject data = (DataObject) get(source, name); final DataObject data = (DataObject) get(source, name);
Assert.exists(data, DataObject.class); Assert.exists(data, DataObject.class);
final DomainObject domain = domain(data); final DomainObject domain = domain(data);
checkXmlCache(domain);
m_traversed.add(domain, prop.getAssociatedProperty()); m_traversed.add(domain, prop.getAssociatedProperty());
@ -307,12 +308,13 @@ class DomainCopier extends DomainService {
} else if (prop.isNullable()) { } else if (prop.isNullable()) {
s_log.debug("The property is a 0..1 association"); s_log.debug("The property is a 0..1 association");
final DataObject data = (DataObject) get(source, name); final DataObject data = (DataObject) get(source, name);
if (data == null) { if (data == null) {
set(target, name, null); set(target, name, null);
} else { } else {
final DomainObject domain = domain(data); final DomainObject domain = domain(data);
checkXmlCache(domain);
m_traversed.add(domain, prop.getAssociatedProperty()); m_traversed.add(domain, prop.getAssociatedProperty());
@ -362,6 +364,7 @@ class DomainCopier extends DomainService {
m_traversed.add(selem, reverse); m_traversed.add(selem, reverse);
final DomainObject telem = copy(source, target, selem, prop); final DomainObject telem = copy(source, target, selem, prop);
checkXmlCache(telem);
DataObject tgtLink = null; DataObject tgtLink = null;
@ -469,16 +472,31 @@ class DomainCopier extends DomainService {
return contains(object.getOID() + "." + prop.getName()); return contains(object.getOID() + "." + prop.getName());
} }
} }
protected final class WrapperDomainObject extends DomainObject { protected final class WrapperDomainObject extends DomainObject {
public WrapperDomainObject(DataObject dobj) { public WrapperDomainObject(final DataObject dobj) {
super(dobj); super(dobj);
} }
public WrapperDomainObject(OID oid) { public WrapperDomainObject(final OID oid) {
super(oid); super(oid);
} }
} }
/**
* Helper method for invalidating the cached XML of associated objects when an item is (re-)published.
*
* @param dobj
*/
private void checkXmlCache(final DomainObject dobj) {
if ((dobj instanceof ContentItem) && CMSConfig.getInstance().getEnableXmlCache()) {
final ContentItem item = (ContentItem) dobj;
XMLDeliveryCache.getInstance().removeFromCache(item.getOID());
}
}
} }

View File

@ -19,7 +19,6 @@
package com.arsdigita.cms.dispatcher; package com.arsdigita.cms.dispatcher;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.caching.CacheTable;
import com.arsdigita.cms.CMS; import com.arsdigita.cms.CMS;
import com.arsdigita.cms.CMSConfig; import com.arsdigita.cms.CMSConfig;
import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentItem;
@ -27,6 +26,7 @@ import com.arsdigita.cms.ContentItemXMLRenderer;
import com.arsdigita.cms.ExtraXMLGenerator; import com.arsdigita.cms.ExtraXMLGenerator;
import com.arsdigita.cms.SecurityManager; import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.UserDefinedContentItem; import com.arsdigita.cms.UserDefinedContentItem;
import com.arsdigita.cms.XMLDeliveryCache;
import com.arsdigita.cms.util.GlobalizationUtil; import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.domain.DataObjectNotFoundException; import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.domain.DomainObjectFactory;
@ -42,7 +42,6 @@ import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.metadata.Property; import com.arsdigita.persistence.metadata.Property;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
import java.util.HashMap;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -84,17 +83,6 @@ public class SimpleXMLGenerator implements XMLGenerator {
*/ */
private String itemElemName = "cms:item"; private String itemElemName = "cms:item";
private String itemElemNs = CMS.CMS_XML_NS; private String itemElemNs = CMS.CMS_XML_NS;
//Cache for generated XML
private static final CacheTable CACHE = new CacheTable(
SimpleXMLGenerator.class.getName() + "Cache",
CMSConfig.getInstance().getXmlCacheSize(),
CMSConfig.getInstance().getXmlCacheAge(),
true);
//Stores the master ID of the cached items and the ID of cached version. Used to delete obsolete entries in the
//cash after republishing
private static final Map<String, String> CACHED_ITEMS = new HashMap<String, String>();
//private static final Map<OID, Element> cache = new HashMap<OID, Element>();
//private static final boolean USE_CACHE = false;
// Register general purpose adaptor for all content items // Register general purpose adaptor for all content items
static { static {
@ -201,29 +189,14 @@ public class SimpleXMLGenerator implements XMLGenerator {
// This is the preferred method // This is the preferred method
//final Element content = startElement(useContext, parent); //final Element content = startElement(useContext, parent);
final Element content; final Element content = startElement(useContext);
if (CMSConfig.getInstance().getEnableXmlCache() && (CACHE.get(item.getOID().toString()) != null)) { s_log.debug("Item is not in cache, generating item.");
s_log.debug("Item found in cache, using cached XML");
final Element cached = (Element) CACHE.get(item.getOID().toString());
//parent.importElement(content);
cached.syncDocs();
content = startElement(useContext); final XMLDeliveryCache xmlCache = XMLDeliveryCache.getInstance();
final Iterator entries = cached.getAttributes().entrySet().iterator();
Map.Entry entry; if (CMSConfig.getInstance().getEnableXmlCache() && xmlCache.isCached(item.getOID(), useContext, listMode)) {
while (entries.hasNext()) { xmlCache.retrieveFromCache(content, item.getOID(), useContext, listMode);
entry = (Map.Entry) entries.next();
content.addAttribute((String) entry.getKey(), (String) entry.getValue());
}
final Iterator childs = cached.getChildren().iterator();
while (childs.hasNext()) {
copyElement(content, (Element) childs.next());
}
} else { } else {
s_log.debug("Item is not in cache, generating item.");
content = startElement(useContext);
final ContentItemXMLRenderer renderer = new ContentItemXMLRenderer(content); final ContentItemXMLRenderer renderer = new ContentItemXMLRenderer(content);
renderer.setWrapAttributes(true); renderer.setWrapAttributes(true);
@ -241,72 +214,35 @@ public class SimpleXMLGenerator implements XMLGenerator {
//parent.addContent(content); //parent.addContent(content);
if (CMSConfig.getInstance().getEnableXmlCache()) { //Only item XML Cache End
validateCache(item);
}
//Only published items
//Only the XML of the item itself, no extra XML
if (CMSConfig.getInstance().getEnableXmlCache() && item.isLiveVersion()) {
s_log.debug("Putting item item into the cache.");
final Element cachedElem = startCachedElement(useContext);
final Iterator entries = content.getAttributes().entrySet().iterator();
Map.Entry entry;
while (entries.hasNext()) {
entry = (Map.Entry) entries.next();
cachedElem.addAttribute((String) entry.getKey(), (String) entry.getValue());
}
final Iterator childs = content.getChildren().iterator();
while (childs.hasNext()) {
//cachedElem.newChildElement((Element) childs.next());
copyElement(cachedElem, (Element) childs.next());
}
CACHE.put(item.getOID().toString(), cachedElem);
}
}
//Only item XML Cache End
// s_log.debug("Content elem content: "); // s_log.debug("Content elem content: ");
// logElementTree(content); // logElementTree(content);
// s_log.debug("Content elem content end -- "); // s_log.debug("Content elem content end -- ");
/* /*
* 2011-08-27 jensp: Introduced to remove the annoying special templates * 2011-08-27 jensp: Introduced to remove the annoying special templates
* for MultiPartArticle, SiteProxy and others. The method called * for MultiPartArticle, SiteProxy and others. The method called
* here was already definied but not used. * here was already definied but not used.
* *
* 2011-10-23 jensp: It is now possible to disable the use of * 2011-10-23 jensp: It is now possible to disable the use of
* extra XML. * extra XML.
*/ */
//final long extraXMLStart = System.nanoTime(); //final long extraXMLStart = System.nanoTime();
if (useExtraXml) { if (useExtraXml) {
for (ExtraXMLGenerator generator : item.getExtraXMLGenerators()) { for (ExtraXMLGenerator generator : item.getExtraXMLGenerators()) {
generator.setListMode(listMode); generator.setListMode(listMode);
generator.generateXML(item, content, state); generator.generateXML(item, content, state);
}
}
//Only published items
//Only the XML of the item itself, no extra XML
if (CMSConfig.getInstance().getEnableXmlCache() && item.isLiveVersion()) {
xmlCache.cache(item.getOID(), item, content, useContext, listMode);
} }
} }
// System.out.
// printf("Rendered ExtraXML in %d ms\n", (System.nanoTime() - extraXMLStart) / 1000000);
// System.out.printf(" -----\n");
//Complete cache begin
// if (CMSConfig.getInstance().getEnableXmlCache() && item.isLiveVersion()) {
// final Element cachedElem = startElement(useContext);
// final Iterator entries = content.getAttributes().entrySet().iterator();
// Map.Entry entry;
// while (entries.hasNext()) {
// entry = (Map.Entry) entries.next();
// cachedElem.addAttribute((String) entry.getKey(), (String) entry.getValue());
// }
// final Iterator childs = content.getChildren().iterator();
// while (childs.hasNext()) {
// cachedElem.newChildElement((Element) childs.next());
// }
// CACHE.put(item.getOID().toString(), cachedElem);
// }
// }
//complete cache end
if (PermissionService.checkPermission(edit)) { if (PermissionService.checkPermission(edit)) {
final ItemResolver resolver = item.getContentSection().getItemResolver(); final ItemResolver resolver = item.getContentSection().getItemResolver();
@ -506,20 +442,4 @@ public class SimpleXMLGenerator implements XMLGenerator {
return builder.toString(); return builder.toString();
} }
private void validateCache(final ContentItem item) {
if (item.isDraftVersion()) {
//Draft version are not cached
return;
}
final String itemId = item.getOID().toString();
final String masterId = item.getDraftVersion().getOID().toString();
final String cachedId = CACHED_ITEMS.get(masterId);
if ((cachedId != null)
&& !cachedId.equals(itemId)) {
CACHE.remove(cachedId);
}
}
} }

View File

@ -16,7 +16,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
*/ */
package com.arsdigita.ui.admin; package com.arsdigita.ui.admin;
import com.arsdigita.bebop.Page; import com.arsdigita.bebop.Page;
@ -47,55 +46,55 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* Web Developer Support Application Servlet class, central entry point to * Web Developer Support Application Servlet class, central entry point to create and process the applications UI.
* create and process the applications UI. *
* * We should have subclassed BebopApplicationServlet but couldn't overwrite doService() method to add permission
* We should have subclassed BebopApplicationServlet but couldn't overwrite * checking. So we use our own page mapping. The general logic is the same as for BebopApplicationServlet.
* doService() method to add permission checking. So we use our own page * {
* mapping. The general logic is the same as for BebopApplicationServlet. *
* {@see com.arsdigita.bebop.page.BebopApplicationServlet} * @see com.arsdigita.bebop.page.BebopApplicationServlet}
* *
* @author pb * @author pb
*/ */
public class AdminServlet extends BaseApplicationServlet public class AdminServlet extends BaseApplicationServlet
implements AdminConstants{ implements AdminConstants {
/** Logger instance for debugging */ /**
* Logger instance for debugging
*/
private static final Logger s_log = Logger.getLogger( private static final Logger s_log = Logger.getLogger(
AdminServlet.class.getName()); AdminServlet.class.getName());
/**
/** URL (pathinfo) -> Page object mapping. Based on it (and the http * URL (pathinfo) -> Page object mapping. Based on it (and the http request url) the doService method to selects a
* request url) the doService method to selects a page to display */ * page to display
*/
private final Map m_pages = new HashMap(); private final Map m_pages = new HashMap();
/** /**
* User extension point, overwrite this method to setup a URL - page mapping * User extension point, overwrite this method to setup a URL - page mapping
* *
* @throws ServletException * @throws ServletException
*/ */
@Override @Override
public void doInit() throws ServletException { public void doInit() throws ServletException {
addPage("/", buildAdminIndexPage()); // index page at address ~/ds addPage("/", buildAdminIndexPage()); // index page at address ~/ds
// addPage("/index.jsp", buildIndexPage()); // index page at address ~/ds // addPage("/index.jsp", buildIndexPage()); // index page at address ~/ds
} }
/** /**
* Central service method, checks for required permission, determines the * Central service method, checks for required permission, determines the requested page and passes the page object
* requested page and passes the page object to PresentationManager. * to PresentationManager.
*/ */
public final void doService(HttpServletRequest sreq, public final void doService(HttpServletRequest sreq,
HttpServletResponse sresp, HttpServletResponse sresp,
Application app) Application app)
throws ServletException, IOException { throws ServletException, IOException {
// /////// Some preparational steps /////////////// // /////// Some preparational steps ///////////////
/* Determine access privilege: only logged in users may access DS */ /* Determine access privilege: only logged in users may access DS */
@ -104,8 +103,7 @@ public class AdminServlet extends BaseApplicationServlet
throw new LoginSignal(sreq); throw new LoginSignal(sreq);
} }
/* Determine access privilege: Admin privileges must be granted */ /* Determine access privilege: Admin privileges must be granted */
PermissionDescriptor admin = new PermissionDescriptor PermissionDescriptor admin = new PermissionDescriptor(PrivilegeDescriptor.ADMIN, app, party);
(PrivilegeDescriptor.ADMIN, app, party);
if (!PermissionService.checkPermission(admin)) { if (!PermissionService.checkPermission(admin)) {
throw new AccessDeniedException("User is not an administrator"); throw new AccessDeniedException("User is not an administrator");
} }
@ -123,7 +121,7 @@ public class AdminServlet extends BaseApplicationServlet
* trailing '/' if a "virtual" page, i.e. not a real jsp, but * trailing '/' if a "virtual" page, i.e. not a real jsp, but
* result of a servlet mapping. But Application requires url * result of a servlet mapping. But Application requires url
* NOT to end with a trailing '/' for legacy free applications. */ * NOT to end with a trailing '/' for legacy free applications. */
pathInfo = pathInfo.substring(0, pathInfo.length()-1); pathInfo = pathInfo.substring(0, pathInfo.length() - 1);
} }
final Page page = (Page) m_pages.get(pathInfo); final Page page = (Page) m_pages.get(pathInfo);
@ -140,13 +138,12 @@ public class AdminServlet extends BaseApplicationServlet
sresp.sendError(404, "No such page for path " + pathInfo); sresp.sendError(404, "No such page for path " + pathInfo);
} }
}
}
/** /**
* Adds one pair of Url - Page to the internal hash map, used as a cache. * Adds one pair of Url - Page to the internal hash map, used as a cache.
* *
* @param pathInfo url stub for a page to display * @param pathInfo url stub for a page to display
* @param page Page object to display * @param page Page object to display
*/ */
@ -171,11 +168,11 @@ public class AdminServlet extends BaseApplicationServlet
p.addGlobalStateParam(USER_ID_PARAM); p.addGlobalStateParam(USER_ID_PARAM);
p.addGlobalStateParam(GROUP_ID_PARAM); p.addGlobalStateParam(GROUP_ID_PARAM);
// p.addGlobalStateParam(APPLICATIONS_ID_PARAM); p.addGlobalStateParam(APPLICATIONS_ID_PARAM);
/* Create User split panel. */ /* Create User split panel. */
AdminSplitPanel userSplitPanel = AdminSplitPanel userSplitPanel =
new AdminSplitPanel(USER_NAVBAR_TITLE); new AdminSplitPanel(USER_NAVBAR_TITLE);
UserBrowsePane browsePane = new UserBrowsePane(); UserBrowsePane browsePane = new UserBrowsePane();
@ -187,19 +184,19 @@ public class AdminServlet extends BaseApplicationServlet
new UserSearchPane(userSplitPanel, browsePane)); new UserSearchPane(userSplitPanel, browsePane));
userSplitPanel.addTab(USER_TAB_CREATE_USER, userSplitPanel.addTab(USER_TAB_CREATE_USER,
new CreateUserPane(userSplitPanel)); new CreateUserPane(userSplitPanel));
/* /*
* Create group administration panel * Create group administration panel
*/ */
GroupAdministrationTab groupAdministrationTab = GroupAdministrationTab groupAdministrationTab =
new GroupAdministrationTab(); new GroupAdministrationTab();
/* /*
* Create group administration panel * Create group administration panel
*/ */
// ApplicationsAdministrationTab appsAdministrationTab = ApplicationsAdministrationTab appsAdministrationTab =
// new ApplicationsAdministrationTab(); new ApplicationsAdministrationTab();
// Create the Admin's page tab bar, currently 2 elements: user & groups // Create the Admin's page tab bar, currently 2 elements: user & groups
TabbedPane tb = new TabbedPane(); TabbedPane tb = new TabbedPane();
@ -207,19 +204,15 @@ public class AdminServlet extends BaseApplicationServlet
tb.addTab(USER_TAB_TITLE, userSplitPanel); tb.addTab(USER_TAB_TITLE, userSplitPanel);
tb.addTab(GROUP_TAB_TITLE, groupAdministrationTab); tb.addTab(GROUP_TAB_TITLE, groupAdministrationTab);
// tb.addTab(APPLICATIONS_TAB_TITLE, appsAdministrationTab); tb.addTab(APPLICATIONS_TAB_TITLE, appsAdministrationTab);
browsePane.setTabbedPane(tb); browsePane.setTabbedPane(tb);
browsePane.setGroupAdministrationTab(groupAdministrationTab); browsePane.setGroupAdministrationTab(groupAdministrationTab);
// browsePane.setAppsAdministrationTab(appsAdministrationTab); //browsePane.setAppsAdministrationTab(appsAdministrationTab);
p.add(tb); p.add(tb);
p.lock(); p.lock();
return p; return p;
} }
} }

View File

@ -5,22 +5,36 @@
package com.arsdigita.ui.admin; package com.arsdigita.ui.admin;
import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SplitPanel; import com.arsdigita.bebop.SplitPanel;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.ChangeEvent; import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener; import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.LockableImpl;
import com.arsdigita.web.Application;
import com.arsdigita.web.ApplicationCollection;
/** /**
* *
* @author pb * @author pb
* @author Jens Pelzetter
*/ */
public class ApplicationsAdministrationTab extends BoxPanel public class ApplicationsAdministrationTab extends BoxPanel
implements AdminConstants, ChangeListener { implements AdminConstants, ChangeListener {
private GlobalizedMessage m_title; private GlobalizedMessage m_title;
/** /**
* Constructor * Constructor
*/ */
@ -29,35 +43,214 @@ public class ApplicationsAdministrationTab extends BoxPanel
// m_title = "TEST für ein neues Pannel"; // m_title = "TEST für ein neues Pannel";
setClassAttr("sidebarNavPanel"); setClassAttr("sidebarNavPanel");
setAttribute("navbar-title", "Sitemap"); setAttribute("navbar-title", "Sitemap");
// m_componentList = new ArrayList(); // m_componentList = new ArrayList();
// m_keys = new ArrayList(); // m_keys = new ArrayList();
BoxPanel box = new BoxPanel(); final BoxPanel box = new BoxPanel();
box.setClassAttr("main"); box.setClassAttr("main");
SplitPanel panel = new SplitPanel(); final SplitPanel panel = new SplitPanel();
panel.setClassAttr("sidebarNavPanel"); panel.setClassAttr("sidebarNavPanel");
panel.setRightComponent(box); panel.setRightComponent(box);
box.add(new ApplicationsTable());
add(panel);
} }
/** /**
* *
* @param e * @param e
*/ */
@Override
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
PageState ps = e.getPageState(); PageState ps = e.getPageState();
// String key = (String) m_tree.getSelectedKey(ps); // String key = (String) m_tree.getSelectedKey(ps);
// added cg - reset existing group add panel to the search screen // added cg - reset existing group add panel to the search screen
// when a new group is selected from the tree // when a new group is selected from the tree
// ps.setValue(GROUP_ID_PARAM, new BigDecimal(key)); // ps.setValue(GROUP_ID_PARAM, new BigDecimal(key));
// int selectedIndex = Integer.parseInt((String) m_list.getSelectedKey(ps)); // int selectedIndex = Integer.parseInt((String) m_list.getSelectedKey(ps));
// setTab(selectedIndex, ps); // setTab(selectedIndex, ps);
} }
private class ApplicationsTable extends Table implements TableActionListener {
private static final String COL_APP_CLASS = "col_app_class";
private static final String COL_APP_TYPE = "col_app_type";
private static final String COL_APP_VIEW_URL = "col_app_view_url";
private static final String COL_APP_ADMIN_URL = "col_app_admin_url";
private static final String COL_APP_SINGLETON = "col_app_singleton";
public ApplicationsTable() {
super();
setEmptyView(new Label("No applications installed."));
final TableColumnModel colModel = getColumnModel();
colModel.add(new TableColumn(
0,
"App Class",
COL_APP_CLASS));
colModel.add(new TableColumn(
1,
"App Type",
COL_APP_TYPE));
colModel.add(new TableColumn(
2,
"App View URL",
COL_APP_VIEW_URL));
colModel.add(new TableColumn(
3,
"Is Singleton?",
COL_APP_SINGLETON));
setModelBuilder(new ApplicationsTableModelBuilder());
colModel.get(0).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
return new Label(value.toString());
}
});
colModel.get(1).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
return new Label(value.toString());
}
});
colModel.get(2).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
return new Link(value.toString(), value.toString());
}
});
colModel.get(3).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
return new Label(value.toString());
}
});
addTableActionListener(this);
}
private class ApplicationsTableModelBuilder extends LockableImpl implements TableModelBuilder {
@Override
public TableModel makeModel(final Table table, final PageState state) {
return new ApplicationsTableModel(table);
}
}
private class ApplicationsTableModel implements TableModel {
private final Table table;
private final ApplicationCollection apps;
private Application app;
public ApplicationsTableModel(final Table table) {
this.table = table;
apps = Application.retrieveAllApplications();
apps.addOrder("objectType");
}
@Override
public int getColumnCount() {
return table.getColumnModel().size();
}
@Override
public boolean nextRow() {
boolean ret;
if ((apps != null) && apps.next()) {
app = apps.getApplication();
ret = true;
} else {
ret = false;
}
return ret;
}
@Override
public Object getElementAt(final int columnIndex) {
switch (columnIndex) {
case 0:
return String.format("%s (%s)", app.getObjectType().getName(), app.getClass().getName());
case 1:
return app.getApplicationType().getTitle();
case 2:
return app.getPath();
case 3:
return Boolean.toString(app.getApplicationType().isSingleton());
default:
return null;
}
}
@Override
public Object getKeyAt(final int columnIndex) {
return app.getID();
}
private String constructAppPath(final Application app) {
if (app.getParentApplication() == null) {
return app.getPath();
} else {
return String.format("%s/%s", constructAppPath(app.getParentApplication()), app.getPath());
}
}
}
@Override
public void cellSelected(final TableActionEvent event) {
//Nothing for now
}
@Override
public void headSelected(final TableActionEvent event) {
//Nothing for now
}
}
} }

View File

@ -68,17 +68,14 @@ public class Application extends Resource {
/** Logger instance for debugging. */ /** Logger instance for debugging. */
private static final Logger s_log = Logger.getLogger(Application.class); private static final Logger s_log = Logger.getLogger(Application.class);
/** PDL property, basic object type for all applications of this type */ /** PDL property, basic object type for all applications of this type */
public static final String BASE_DATA_OBJECT_TYPE = public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.web.Application"; "com.arsdigita.web.Application";
/** PDL property, the applications base URL. */ /** PDL property, the applications base URL. */
public static final String PRIMARY_URL = "primaryURL"; public static final String PRIMARY_URL = "primaryURL";
/** Internal String to denote a Path delimiter. */ /** Internal String to denote a Path delimiter. */
private static final String SLASH = "/"; private static final String SLASH = "/";
/** /**
* Provides the base object type. * Provides the base object type.
*/ */
@ -124,13 +121,13 @@ public class Application extends Resource {
* without parent and without an explicit URL fragment * without parent and without an explicit URL fragment
*/ */
public static Application createRootApplication( public static Application createRootApplication(
final ApplicationType type, final ApplicationType type,
final String title, final String title,
final boolean createContainerGroup) { final boolean createContainerGroup) {
if (Assert.isEnabled()) { if (Assert.isEnabled()) {
Assert.exists(type, ApplicationType.class); Assert.exists(type, ApplicationType.class);
Assert.exists(title, String.class); Assert.exists(title, String.class);
// Assert.isTrue(type.m_legacyFree); // Assert.isTrue(type.m_legacyFree);
} }
return Application.make(type, null, title, null, createContainerGroup); return Application.make(type, null, title, null, createContainerGroup);
@ -151,7 +148,7 @@ public class Application extends Resource {
final String title, final String title,
final Application parent) { final Application parent) {
s_log.debug("Create Application"); s_log.debug("Create Application");
return Application.createApplication(type,fragment,title,parent,false); return Application.createApplication(type, fragment, title, parent, false);
} }
// For convenience. // For convenience.
@ -168,7 +165,7 @@ public class Application extends Resource {
final String title, final String title,
final Application parent) { final Application parent) {
return Application.createApplication(typeName,fragment,title,parent,false); return Application.createApplication(typeName, fragment, title, parent, false);
} }
/** /**
@ -181,20 +178,20 @@ public class Application extends Resource {
* @return * @return
*/ */
public static Application createApplication( public static Application createApplication(
final String typeName, final String typeName,
final String fragment, final String fragment,
final String title, final String title,
final Application parent, final Application parent,
final boolean createContainerGroup) { final boolean createContainerGroup) {
final ApplicationType type = ApplicationType final ApplicationType type = ApplicationType
.retrieveApplicationTypeForApplication( .retrieveApplicationTypeForApplication(
typeName); typeName);
if (type == null) { if (type == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"No ApplicationType found for type name " + typeName); "No ApplicationType found for type name " + typeName);
} }
return Application.createApplication(type,fragment, return Application.createApplication(type, fragment,
title,parent,createContainerGroup); title, parent, createContainerGroup);
} }
/** /**
@ -211,20 +208,20 @@ public class Application extends Resource {
* @return * @return
*/ */
public static Application createApplication( public static Application createApplication(
final ApplicationType type, final ApplicationType type,
final String fragment, final String fragment,
final String title, final String title,
final Application parent, final Application parent,
final boolean createContainerGroup) { final boolean createContainerGroup) {
if (Assert.isEnabled()) { if (Assert.isEnabled()) {
Assert.exists(type, ApplicationType.class); Assert.exists(type, ApplicationType.class);
Assert.exists(fragment, String.class); Assert.exists(fragment, String.class);
Assert.exists(title, String.class); Assert.exists(title, String.class);
Assert.isTrue(!fragment.equals(""), Assert.isTrue(!fragment.equals(""),
"The URL fragment must not be the empty string"); "The URL fragment must not be the empty string");
} }
return Application.make(type,fragment,title,parent, return Application.make(type, fragment, title, parent,
createContainerGroup); createContainerGroup);
} }
@ -243,17 +240,16 @@ public class Application extends Resource {
final String title, final String title,
final Application parent, final Application parent,
final boolean createContainerGroup) { final boolean createContainerGroup) {
final Application app = (Application) Resource.createResource(type, final Application app = (Application) Resource.createResource(type,
title, title,
parent); parent);
if (createContainerGroup) { if (createContainerGroup) {
app.createGroup(); app.createGroup();
} }
if (Assert.isEnabled() && fragment != null) { if (Assert.isEnabled() && fragment != null) {
Assert.isTrue(fragment.indexOf('/') == -1, Assert.isTrue(fragment.indexOf('/') == -1,
"The URL fragment must not contain " + "The URL fragment must not contain " + "slashes; I got '" + fragment + "'");
"slashes; I got '" + fragment + "'");
} }
/* Problem with "slash or not slash" /* Problem with "slash or not slash"
@ -285,7 +281,6 @@ public class Application extends Resource {
return app; return app;
} }
/** /**
* *
* @param id * @param id
@ -338,8 +333,7 @@ public class Application extends Resource {
Assert.exists(obj, ACSObject.class); Assert.exists(obj, ACSObject.class);
ACSObject result = obj.gimmeContainer(); ACSObject result = obj.gimmeContainer();
while (result != null && while (result != null && !(result instanceof Application)) {
!(result instanceof Application)) {
result = result.gimmeContainer(); result = result.gimmeContainer();
} }
@ -355,7 +349,7 @@ public class Application extends Resource {
s_log.debug("retrieveApplicationForPath: " + path); s_log.debug("retrieveApplicationForPath: " + path);
DataCollection dataCollection = DataCollection dataCollection =
SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE); SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE);
dataCollection.addEqualsFilter(PRIMARY_URL, path); dataCollection.addEqualsFilter(PRIMARY_URL, path);
@ -364,7 +358,7 @@ public class Application extends Resource {
dataCollection.close(); dataCollection.close();
return Application.retrieveApplication(dataObject); return Application.retrieveApplication(dataObject);
} else { } else {
s_log.debug("retrieveApplicationForPath: No application found on " + path); s_log.debug("retrieveApplicationForPath: No application found on " + path);
return null; return null;
} }
} }
@ -372,7 +366,6 @@ public class Application extends Resource {
// /////////////////////// // ///////////////////////
// Association properties // Association properties
// /////////////////////// // ///////////////////////
/** /**
* *
* @return (Cannot return null.) * @return (Cannot return null.)
@ -445,14 +438,12 @@ public class Application extends Resource {
* @param applicationType * @param applicationType
* @return * @return
*/ */
public ApplicationCollection getChildApplicationsForType public ApplicationCollection getChildApplicationsForType(String applicationType) {
(String applicationType) {
ApplicationCollection children = getChildApplications(); ApplicationCollection children = getChildApplications();
children.addEqualsFilter("objectType", applicationType); children.addEqualsFilter("objectType", applicationType);
return children; return children;
} }
// Can return null. // Can return null.
/** /**
* @deprecated Use {@link * @deprecated Use {@link
@ -471,7 +462,6 @@ public class Application extends Resource {
// ////////////////// // //////////////////
// Member properties // Member properties
// ////////////////// // //////////////////
/** /**
* Returns the path to this application through the dispatcher. * Returns the path to this application through the dispatcher.
* This path ends in a slash. Returns <code>null</code> if the * This path ends in a slash. Returns <code>null</code> if the
@ -526,26 +516,26 @@ public class Application extends Resource {
public final void setPath(String path) { public final void setPath(String path) {
if (Assert.isEnabled()) { if (Assert.isEnabled()) {
Assert.exists(path, String.class); Assert.exists(path, String.class);
/* Modified by pboy April 2011 /* Modified by pboy April 2011
* This Assert statement prevents a trailing slash. setPath is currently called * This Assert statement prevents a trailing slash. setPath is currently called
* only by Applicatiom#make which creates a LEGACY FREE application. * only by Applicatiom#make which creates a LEGACY FREE application.
* Legacy compatible applications are currently created WITH a trailing slash * Legacy compatible applications are currently created WITH a trailing slash
* (see e.g. SiteNode#setURL oder SiteNode#getURLFromParent.) Therefore for the * (see e.g. SiteNode#setURL oder SiteNode#getURLFromParent.) Therefore for the
* time beeing if we must support legacy free and legacy compatible applications * time beeing if we must support legacy free and legacy compatible applications
* in parallel we have to use a trailing slash for legacy free applications, * in parallel we have to use a trailing slash for legacy free applications,
* otherwise they will not be found by methods like retrieveApplicationForPath() * otherwise they will not be found by methods like retrieveApplicationForPath()
* which is called by legacy compatible apps including a trailing slash. If * which is called by legacy compatible apps including a trailing slash. If
* legacy free apps are stored without trailing slash the search will never match. * legacy free apps are stored without trailing slash the search will never match.
* The same is true as long as we mix old style dispatcher code with new style * The same is true as long as we mix old style dispatcher code with new style
* servlet code. * servlet code.
*/ */
// Assert.isTrue // Assert.isTrue
// (path.equals("") || (path.startsWith(SLASH) // (path.equals("") || (path.startsWith(SLASH)
// && !path.endsWith(SLASH)), // && !path.endsWith(SLASH)),
// "The path must either be the empty string (for the " + // "The path must either be the empty string (for the " +
// "default application) or it must start with '/' and *not* " + // "default application) or it must start with '/' and *not* " +
// "end in '/'; I got '" + path + "'"); // "end in '/'; I got '" + path + "'");
} }
set(PRIMARY_URL, path); set(PRIMARY_URL, path);
} }
@ -560,33 +550,30 @@ public class Application extends Resource {
*/ */
public static ApplicationCollection retrieveAllApplications() { public static ApplicationCollection retrieveAllApplications() {
DataCollection dataCollection = DataCollection dataCollection =
SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE); SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE);
// exclude all portlets (no application at all) and portal panes // exclude all portlets (no application at all) and portal panes
// (no application but sort of "sub-application"). // (no application but sort of "sub-application").
dataCollection.addEqualsFilter dataCollection.addEqualsFilter("resourceType.hasFullPageView", Boolean.TRUE);
("resourceType.hasFullPageView", Boolean.TRUE);
ApplicationCollection apps = new ApplicationCollection(dataCollection);
ApplicationCollection apps = new ApplicationCollection
(dataCollection);
return apps; return apps;
} }
/** /**
* Retrieve all installed applications (portlets excluded). * Retrieve all installed applications (portlets excluded).
* @return a collection of installed * @return a collection of installed
*/ */
public static ApplicationCollection retrieveAllApplications(String public static ApplicationCollection retrieveAllApplications(String applicationType) {
applicationType) {
DataCollection dataCollection = SessionManager.getSession() DataCollection dataCollection = SessionManager.getSession()
.retrieve(BASE_DATA_OBJECT_TYPE); .retrieve(BASE_DATA_OBJECT_TYPE);
// exclude all portlets (no application at all) and portal panes // exclude all portlets (no application at all) and portal panes
// (no application but sort of "sub-application"). // (no application but sort of "sub-application").
dataCollection.addEqualsFilter dataCollection.addEqualsFilter("resourceType.hasFullPageView", Boolean.TRUE);
("resourceType.hasFullPageView", Boolean.TRUE);
dataCollection.addEqualsFilter("objectType", applicationType); dataCollection.addEqualsFilter("objectType", applicationType);
ApplicationCollection apps = new ApplicationCollection(dataCollection); ApplicationCollection apps = new ApplicationCollection(dataCollection);
return apps; return apps;
@ -598,10 +585,10 @@ public class Application extends Resource {
* @param path * @param path
* @return * @return
*/ */
public static boolean isInstalled (String applicationObjectType, public static boolean isInstalled(String applicationObjectType,
String path) { String path) {
DataCollection dataCollection = DataCollection dataCollection =
SessionManager.getSession().retrieve(applicationObjectType); SessionManager.getSession().retrieve(applicationObjectType);
dataCollection.addEqualsFilter(PRIMARY_URL, path); dataCollection.addEqualsFilter(PRIMARY_URL, path);
@ -621,7 +608,7 @@ public class Application extends Resource {
* *
*/ */
public static String getCanonicalURL(String url) { public static String getCanonicalURL(String url) {
String canonicalURL; String canonicalURL;
url = url.trim(); // Remove whitespace url = url.trim(); // Remove whitespace
@ -629,7 +616,7 @@ public class Application extends Resource {
canonicalURL = url.startsWith(SLASH) ? url : (SLASH + url); canonicalURL = url.startsWith(SLASH) ? url : (SLASH + url);
canonicalURL = url.endsWith(SLASH) ? canonicalURL : (canonicalURL + SLASH); canonicalURL = url.endsWith(SLASH) ? canonicalURL : (canonicalURL + SLASH);
return canonicalURL ; return canonicalURL;
} }
/** /**
@ -697,15 +684,15 @@ public class Application extends Resource {
@Override @Override
public void beforeDelete() { public void beforeDelete() {
super.beforeDelete(); super.beforeDelete();
// SiteNode node = getSiteNode(); // SiteNode node = getSiteNode();
// if (node != null) { // if (node != null) {
// node.delete(); // node.delete();
// } // }
} }
/** /**
* *
*/ */
@Override @Override
public void afterDelete() { public void afterDelete() {
BaseDispatcher.scheduleRefresh(); BaseDispatcher.scheduleRefresh();
@ -737,7 +724,7 @@ public class Application extends Resource {
*/ */
public void createGroup() { public void createGroup() {
Assert.isEqual(getGroup(), null, Assert.isEqual(getGroup(), null,
"Group has already been created for Application " + getTitle()); "Group has already been created for Application " + getTitle());
Group group = new Group(); Group group = new Group();
group.setName(getTitle() + " Groups"); group.setName(getTitle() + " Groups");
@ -756,7 +743,6 @@ public class Application extends Resource {
} }
/** /**
* . * .
* *
@ -765,7 +751,7 @@ public class Application extends Resource {
* @param title * @param title
*/ */
@Override @Override
public void setTitle (String title) { public void setTitle(String title) {
super.setTitle(title); super.setTitle(title);
Group containerGroup = getGroup(); Group containerGroup = getGroup();
if (containerGroup != null) { if (containerGroup != null) {
@ -781,7 +767,7 @@ public class Application extends Resource {
*/ */
public Group getGroup() { public Group getGroup() {
return (Group) DomainObjectFactory.newInstance( return (Group) DomainObjectFactory.newInstance(
(DataObject) get("containerGroup")); (DataObject) get("containerGroup"));
} }
} }

View File

@ -152,11 +152,14 @@ public class DataCollectionRenderer extends LockableImpl {
Assert.isLocked(this); Assert.isLocked(this);
int pageNumber = pageNum; int pageNumber = pageNum;
final long objectCount = objects.size();
// Quasimodo: Begin // Quasimodo: Begin
// If objects is null or empty, do not insert objectList-element // If objects is null or empty, do not insert objectList-element
// but do insert noContent-element and return immediately // but do insert noContent-element and return immediately
if (objects == null || objects.isEmpty()) { //if (objects == null || objects.isEmpty()) {
if (objects == null || (objectCount == 0)) {
return Navigation.newElement("noContent"); return Navigation.newElement("noContent");
} }
// Quasimodo: End // Quasimodo: End
@ -171,7 +174,7 @@ public class DataCollectionRenderer extends LockableImpl {
return content; return content;
} }
final long objectCount = objects.size();
final int pageCount = (int) Math.ceil((double) objectCount / (double) m_pageSize); final int pageCount = (int) Math.ceil((double) objectCount / (double) m_pageSize);
if (pageNumber < 1) { if (pageNumber < 1) {

View File

@ -18,9 +18,11 @@
package com.arsdigita.navigation.cms; package com.arsdigita.navigation.cms;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.cms.CMSConfig;
import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentItemXMLRenderer; import com.arsdigita.cms.ContentItemXMLRenderer;
import com.arsdigita.cms.ExtraXMLGenerator; import com.arsdigita.cms.ExtraXMLGenerator;
import com.arsdigita.cms.XMLDeliveryCache;
import com.arsdigita.cms.dispatcher.ItemResolver; import com.arsdigita.cms.dispatcher.ItemResolver;
import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.kernel.ACSObject; import com.arsdigita.kernel.ACSObject;
@ -69,45 +71,79 @@ public class CMSDataCollectionRenderer extends DataCollectionRenderer {
ACSObject obj, ACSObject obj,
int index) { int index) {
if (obj != null) { if (obj != null) {
ContentItemXMLRenderer renderer = new ContentItemXMLRenderer(item); if (CMSConfig.getInstance().getEnableXmlCache()
renderer.setRevisitFullObject(false); && (obj instanceof ContentItem)
renderer.setWrapAttributes(true); && XMLDeliveryCache.getInstance().isCached(obj.getOID())) {
renderer.setWrapRoot(false);
renderer.setWrapObjects(false); XMLDeliveryCache.getInstance().retrieveFromCache(item, obj.getOID());
//renderer.walk(obj, SimpleXMLGenerator.ADAPTER_CONTEXT);
createEditLink(item, (ContentItem) obj);
} else {
ContentItemXMLRenderer renderer = new ContentItemXMLRenderer(item);
renderer.setRevisitFullObject(false);
renderer.setWrapAttributes(true);
renderer.setWrapRoot(false);
renderer.setWrapObjects(false);
//renderer.walk(obj, SimpleXMLGenerator.ADAPTER_CONTEXT);
/* jensp 2011-01-03: /* jensp 2011-01-03:
* I needed the option to use different traversal adapters for * I needed the option to use different traversal adapters for
* the object in the detail view and the list view. It is now * the object in the detail view and the list view. It is now
* possible to set the adapter context used from a JSP template, * possible to set the adapter context used from a JSP template,
* using DataCollectionRenderer#setSpecializeObjectsContext(String). * using DataCollectionRenderer#setSpecializeObjectsContext(String).
*/ */
renderer.walk(obj, getSpecializeObjectsContext()); renderer.walk(obj, getSpecializeObjectsContext());
if ((obj instanceof ContentItem) && useExtraXml) { if ((obj instanceof ContentItem) && useExtraXml) {
final ContentItem contentItem = (ContentItem) obj; final ContentItem contentItem = (ContentItem) obj;
for (ExtraXMLGenerator generator : contentItem.getExtraListXMLGenerators()) { for (ExtraXMLGenerator generator : contentItem.getExtraListXMLGenerators()) {
generator.setListMode(true); generator.setListMode(true);
generator.generateXML(contentItem, item, null); generator.generateXML(contentItem, item, null);
} }
XMLDeliveryCache.getInstance().cache(contentItem.getOID(), contentItem, item, "", false);
Party currentParty = Kernel.getContext().getParty(); createEditLink(item, contentItem);
if (currentParty == null) {
currentParty = Kernel.getPublicUser(); // Party currentParty = Kernel.getContext().getParty();
} // if (currentParty == null) {
final PermissionDescriptor edit = new PermissionDescriptor(PrivilegeDescriptor.get( // currentParty = Kernel.getPublicUser();
com.arsdigita.cms.SecurityManager.CMS_EDIT_ITEM), contentItem, currentParty); // }
if (PermissionService.checkPermission(edit)) { //
final ItemResolver resolver = contentItem.getContentSection().getItemResolver(); // final PermissionDescriptor edit = new PermissionDescriptor(PrivilegeDescriptor.get(
final Element editLinkElem = item.newChildElement("editLink"); // com.arsdigita.cms.SecurityManager.CMS_EDIT_ITEM), contentItem, currentParty);
final ContentItem draftItem = contentItem.getDraftVersion(); // if (PermissionService.checkPermission(edit)) {
editLinkElem.setText(resolver.generateItemURL(PageState.getPageState(), // final ItemResolver resolver = contentItem.getContentSection().getItemResolver();
draftItem, // final Element editLinkElem = item.newChildElement("editLink");
contentItem.getContentSection(), // final ContentItem draftItem = contentItem.getDraftVersion();
draftItem.getVersion())); // editLinkElem.setText(resolver.generateItemURL(PageState.getPageState(),
// draftItem,
// contentItem.getContentSection(),
// draftItem.getVersion()));
// }
} }
} }
} }
} }
private void createEditLink(final Element item, final ContentItem contentItem) {
Party currentParty = Kernel.getContext().getParty();
if (currentParty == null) {
currentParty = Kernel.getPublicUser();
}
final PermissionDescriptor edit = new PermissionDescriptor(PrivilegeDescriptor.get(
com.arsdigita.cms.SecurityManager.CMS_EDIT_ITEM), contentItem, currentParty);
if (PermissionService.checkPermission(edit)) {
final ItemResolver resolver = contentItem.getContentSection().getItemResolver();
final Element editLinkElem = item.newChildElement("editLink");
final ContentItem draftItem = contentItem.getDraftVersion();
editLinkElem.setText(resolver.generateItemURL(PageState.getPageState(),
draftItem,
contentItem.getContentSection(),
draftItem.getVersion()));
}
}
} }

View File

@ -93,6 +93,7 @@ public abstract class AbstractObjectList
public Element generateObjectListXML(HttpServletRequest request, public Element generateObjectListXML(HttpServletRequest request,
HttpServletResponse response) { HttpServletResponse response) {
final long start = System.nanoTime();
Assert.isLocked(this); Assert.isLocked(this);
String pageNumberValue = request.getParameter("pageNumber"); String pageNumberValue = request.getParameter("pageNumber");
@ -107,9 +108,13 @@ public abstract class AbstractObjectList
throw new UncheckedWrapperException( throw new UncheckedWrapperException(
"cannot parse page number " + pageNumber, ex); "cannot parse page number " + pageNumber, ex);
} }
final long loadObjectsStart = System.nanoTime();
DataCollection objects = getObjects(request, response); DataCollection objects = getObjects(request, response);
////System.out.printf("Got objects for list in %d ms\n", (System.nanoTime() - loadObjectsStart) / 1000000);
////System.out.printf("(100) Needed %d ms until here...\n", (System.nanoTime() - start) / 1000000);
// Quasimodo: Begin // Quasimodo: Begin
// Limit list to objects in the negotiated language and language invariant items // Limit list to objects in the negotiated language and language invariant items
if (objects != null && objects.size() > 0) { if (objects != null && objects.size() > 0) {
@ -130,8 +135,15 @@ public abstract class AbstractObjectList
} }
} }
// Quasimodo: End // Quasimodo: End
////System.out.printf("(200) Needed %d ms until here...\n", (System.nanoTime() - start) / 1000000);
return m_renderer.generateXML(objects, pageNumber.intValue()); //final long renderStart = System.nanoTime();
final Element listXML = m_renderer.generateXML(objects, pageNumber.intValue());
//System.out.printf("Rendered items of list in %d ms\n", (System.nanoTime() - renderStart) / 1000000);
//System.out.printf("Generated object list in %d ms\n", (System.nanoTime() - start) / 1000000);
return listXML;
} }
} }

View File

@ -211,6 +211,7 @@ public class PersonalPublications implements ContentGenerator {
List<PublicationBundle> publicationList = publications; List<PublicationBundle> publicationList = publications;
Collections.sort(publicationList, new Comparator<PublicationBundle>() { Collections.sort(publicationList, new Comparator<PublicationBundle>() {
@Override
public int compare(final PublicationBundle bundle1, final PublicationBundle bundle2) { public int compare(final PublicationBundle bundle1, final PublicationBundle bundle2) {
final Publication publication1 = bundle1.getPublication(GlobalizationHelper.getNegotiatedLocale(). final Publication publication1 = bundle1.getPublication(GlobalizationHelper.getNegotiatedLocale().
getLanguage()); getLanguage());

View File

@ -31,6 +31,7 @@ public class PublicationExtraXmlGenerator implements ExtraXMLGenerator {
public void generateXML(final ContentItem item, public void generateXML(final ContentItem item,
final Element element, final Element element,
final PageState state) { final PageState state) {
final long start = System.nanoTime();
if (!(item instanceof Publication)) { if (!(item instanceof Publication)) {
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"ExtraXMLGenerator '%s' only supports items of type '%s'.", "ExtraXMLGenerator '%s' only supports items of type '%s'.",
@ -40,7 +41,13 @@ public class PublicationExtraXmlGenerator implements ExtraXMLGenerator {
final Publication publication = (Publication) item; final Publication publication = (Publication) item;
createAuthorsXml(publication, element, state); createAuthorsXml(publication, element, state);
System.out.printf("[%s] Created authors XML in %d ms\n",
PublicationExtraXmlGenerator.class.getName(),
(System.nanoTime() - start) / 1000000);
createSeriesXml(publication, element, state); createSeriesXml(publication, element, state);
System.out.printf("[%s] Created series XML in %d ms\n",
PublicationExtraXmlGenerator.class.getName(),
(System.nanoTime() - start) / 1000000);
if (!listMode) { if (!listMode) {
createOrgaUnitsXml(publication, element, state); createOrgaUnitsXml(publication, element, state);
@ -50,15 +57,22 @@ public class PublicationExtraXmlGenerator implements ExtraXMLGenerator {
createExportLink(format, element, (Publication) item, state); createExportLink(format, element, (Publication) item, state);
} }
} }
System.out.printf("[%s] Created extra XML in %d ms\n",
PublicationExtraXmlGenerator.class.getName(),
(System.nanoTime() - start) / 1000000);
} }
private void createAuthorsXml(final Publication publication, private void createAuthorsXml(final Publication publication,
final Element parent, final Element parent,
final PageState state) { final PageState state) {
final long start = System.nanoTime();
final AuthorshipCollection authors = publication.getAuthors(); final AuthorshipCollection authors = publication.getAuthors();
if ((authors == null) || authors.isEmpty()) { if ((authors == null) || authors.isEmpty()) {
return; return;
} }
System.out.printf("[%s#createAuthorsXML] Got authors in %d ms\n",
PublicationExtraXmlGenerator.class.getName(),
(System.nanoTime() - start) / 1000000);
final Element authorsElem = parent.newChildElement("authors"); final Element authorsElem = parent.newChildElement("authors");
while (authors.next()) { while (authors.next()) {
@ -68,6 +82,9 @@ public class PublicationExtraXmlGenerator implements ExtraXMLGenerator {
authorsElem, authorsElem,
state); state);
} }
System.out.printf("[%s#createAuthorsXML] Created XML for authors in %d ms\n",
PublicationExtraXmlGenerator.class.getName(),
(System.nanoTime() - start) / 1000000);
} }
private void createAuthorXml(final GenericPerson author, private void createAuthorXml(final GenericPerson author,
@ -75,12 +92,17 @@ public class PublicationExtraXmlGenerator implements ExtraXMLGenerator {
final Integer order, final Integer order,
final Element authorsElem, final Element authorsElem,
final PageState state) { final PageState state) {
final long start = System.nanoTime();
final XmlGenerator generator = new XmlGenerator(author); final XmlGenerator generator = new XmlGenerator(author);
generator.setItemElemName("author", ""); generator.setItemElemName("author", "");
generator.addItemAttribute("isEditor", isAuthor.toString()); generator.addItemAttribute("isEditor", isAuthor.toString());
generator.addItemAttribute("order", order.toString()); generator.addItemAttribute("order", order.toString());
generator.setListMode(listMode); generator.setListMode(listMode);
generator.generateXML(state, authorsElem, ""); generator.generateXML(state, authorsElem, "");
System.out.printf("[%s] Created XML for author %s in %d ms\n",
PublicationExtraXmlGenerator.class.getName(),
author.getTitle(),
(System.nanoTime() - start) / 1000000);
} }
private void createOrgaUnitsXml(final Publication publication, private void createOrgaUnitsXml(final Publication publication,