Merged HEAD-QA to HEAD (4.2) (including moving test classes into separate folders)

51903 to 54309 


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@54310 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Samuel Langlois
2013-08-20 17:17:31 +00:00
parent 5a8f6ee635
commit e60d57ea42
70 changed files with 7094 additions and 1988 deletions
@@ -391,25 +391,8 @@ public class Application
{
session.invalidate();
}
// remove the username cookie value
Cookie authCookie = AuthenticationHelper.getAuthCookie(request);
if (authCookie != null)
{
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
if (response.isCommitted())
{
// It's too late to do it now, but we can ask the login page to do it
request.getSession().setAttribute(AuthenticationHelper.SESSION_INVALIDATED, true);
}
else
{
authCookie.setMaxAge(0);
response.addCookie(authCookie);
}
}
}
// Explicitly invalidate the Alfresco ticket. This no longer happens on session expiry to allow for ticket
// 'sharing'
WebApplicationContext wc = FacesContextUtils.getRequiredWebApplicationContext(context);
@@ -53,8 +53,6 @@ public class ContextListener implements ServletContextListener, HttpSessionListe
private static Log logger = LogFactory.getLog(ContextListener.class);
private ServletContext servletContext;
private ServletContextListener enterpriseListener;
private String enterpriseListenerClass = "org.alfresco.enterprise.repo.EnterpriseContextListener";
/**
* @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
@@ -124,51 +122,15 @@ public class ContextListener implements ServletContextListener, HttpSessionListe
}
catch (Exception ex) {}
}
synchronized(this)
{
findEnterpriseListener();
if (enterpriseListener != null)
{
// Perform any extra context initialisation required for enterprise.
enterpriseListener.contextInitialized(event);
}
}
}
protected void findEnterpriseListener()
{
try
{
Class<?> c = Class.forName(enterpriseListenerClass);
enterpriseListener = (ServletContextListener) c.newInstance();
}
catch (ClassNotFoundException e)
{
// It's OK not to have the enterprise context destroyer available.
}
catch (InstantiationException e)
{
logger.error("Failed to instantiate enterprise ServletContextListener.", e);
}
catch (IllegalAccessException e)
{
logger.error("Failed to instantiate enterprise ServletContextListener.", e);
}
}
/**
* {@inheritDoc}
*/
public void contextDestroyed(ServletContextEvent event)
{
synchronized(this)
{
if (enterpriseListener != null)
{
// Perform any extra destruction required for enterprise.
enterpriseListener.contextDestroyed(event);
}
}
// NOOP
}
/**
@@ -188,16 +150,4 @@ public class ContextListener implements ServletContextListener, HttpSessionListe
if (logger.isDebugEnabled())
logger.debug("HTTP session destroyed: " + event.getSession().getId());
}
/**
* Inject a different class name (from the default) for the enterprise ServletContextListener.
* <p>
* Useful for testing.
*
* @param listenerClass Class name to use.
*/
protected void setEnterpriseListenerClass(String listenerClass)
{
this.enterpriseListenerClass = listenerClass;
}
}
@@ -1,81 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.app;
import static org.junit.Assert.*;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
/**
* Tests for the ContextListener class.
*
* @author Matt Ward
*/
@RunWith(MockitoJUnitRunner.class)
public class ContextListenerTest
{
private ContextListener contextListener;
private @Mock ServletContextEvent event;
@Before
public void setUp() throws Exception
{
contextListener = new ContextListener();
contextListener.setEnterpriseListenerClass("org.alfresco.web.app.ContextListenerTest$StubEnterpriseListener");
StubEnterpriseListener.enterpriseDestroyed = false;
}
@Test
public void testContextDestroyed()
{
contextListener.findEnterpriseListener();
contextListener.contextDestroyed(event);
assertTrue("Enterprise contextDestroyed() not executed.", StubEnterpriseListener.enterpriseDestroyed);
}
/**
* ServletContextListener to simulate an enterprise-specific context listener.
*/
protected static class StubEnterpriseListener implements ServletContextListener
{
static boolean enterpriseDestroyed;
@Override
public void contextDestroyed(ServletContextEvent arg0)
{
enterpriseDestroyed = true;
}
@Override
public void contextInitialized(ServletContextEvent arg0)
{
// Noop
}
}
}
@@ -1,116 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.app;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import junit.framework.TestCase;
/**
* Unit test for resource bundle wrapper
*
* @author Roy Wetherall
*/
public class ResourceBundleWrapperTest extends TestCase
{
private static final String BUNDLE_NAME = "org.alfresco.web.app.resourceBundleWrapperTest";
private static final String KEY_1 = "test_key_one";
private static final String KEY_2 = "test_key_two";
private static final String MSG_1 = "Test Key One";
private static final String MSG_2 = "Test Key Two";
/**
* Test adding the bundles
*/
public void test1AddingBundles()
{
// Check that the string's are not added to the bundle
ResourceBundle before = ResourceBundleWrapper.getResourceBundle("alfresco.messages.webclient", Locale.US);
Enumeration<String> keys = before.getKeys();
assertFalse(containsValue(keys, KEY_1));
assertFalse(containsValue(keys, KEY_2));
try
{
before.getString(KEY_1);
fail("Not expecting the key to be there");
}
catch (Throwable exception){};
try
{
before.getString(KEY_2);
fail("Not expecting the key to be there");
}
catch (Throwable exception){};
// Add an additional resource bundle
ResourceBundleWrapper.addResourceBundle(BUNDLE_NAME);
// Check that the string's are now added to the bundle
ResourceBundle after = ResourceBundleWrapper.getResourceBundle("alfresco.messages.webclient", Locale.US);
Enumeration<String> keys2 = after.getKeys();
assertTrue(containsValue(keys2, KEY_1));
assertEquals(after.getString(KEY_1), MSG_1);
assertEquals(after.getString(KEY_2), MSG_2);
}
/**
* Test the bootstrap bean
*/
public void test2Bootstrap()
{
// Use the bootstrap bean to add the bundles
List<String> bundles = new ArrayList<String>(1);
bundles.add(BUNDLE_NAME);
ResourceBundleBootstrap bootstrap = new ResourceBundleBootstrap();
bootstrap.setResourceBundles(bundles);
// Check that the string's are now added to the bundle
ResourceBundle after = ResourceBundleWrapper.getResourceBundle("alfresco.messages.webclient", Locale.US);
Enumeration<String> keys2 = after.getKeys();
assertTrue(containsValue(keys2, KEY_1));
assertTrue(containsValue(keys2, KEY_2));
assertEquals(after.getString(KEY_1), MSG_1);
assertEquals(after.getString(KEY_2), MSG_2);
}
/**
* Check whether the list contains the values
*
* @param values list of values to check
* @param value value to look for
* @return boolean true if value contained, false otherwise
*/
private boolean containsValue(Enumeration<String> values, String value)
{
boolean result = false;
while (values.hasMoreElements() == true)
{
if (values.nextElement().equals(value) == true)
{
result = true;
break;
}
}
return result;
}
}
@@ -1,3 +0,0 @@
test_key_one=Test Key One
test_key_two=Test Key Two
test_key_three=Test Key Three
@@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.extensions.config.ConfigService;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
import org.alfresco.web.config.ClientConfigElement;
@@ -114,6 +115,7 @@ public class AuthenticationFilter extends AbstractLifecycleBean implements Depen
{
// continue filter chaining
chain.doFilter(req, res);
AuthenticationUtil.clearCurrentSecurityContext();
}
}
}
@@ -39,10 +39,10 @@ import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.webdav.auth.RemoteUserMapper;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.portlet.AlfrescoFacesPortlet;
@@ -85,6 +85,7 @@ public final class AuthenticationHelper
private static final String REMOTE_USER_MAPPER = "RemoteUserMapper";
private static final String UNPROTECTED_AUTH_SERVICE = "authenticationService";
private static final String PERSON_SERVICE = "personService";
private static final String AUTHORITY_SERVICE = "AuthorityService";
/** cookie names */
private static final String COOKIE_ALFUSER = "alfUser0";
@@ -604,8 +605,9 @@ public final class AuthenticationHelper
// If the remote user mapper is configured, we may be able to map in an externally authenticated user
if (userId != null)
{
AuthorityService authorityService = (AuthorityService) wc.getBean(AUTHORITY_SERVICE);
// We have a previously-cached user with the wrong identity - replace them
if (user != null && !user.getUserName().equals(userId))
if (user != null && !authorityService.isGuestAuthority(user.getUserName()) && !user.getUserName().equals(userId))
{
if (logger.isDebugEnabled())
logger.debug("We have a previously-cached user with the wrong identity - replace them");
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2005-2013 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.app.servlet;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import net.sf.acegisecurity.context.ContextHolder;
/**
* Clears security context. It should follow Authentication filters in the chain and should be mapped for CMIS requests only
*
* @author Dmitry Velichkevich
* @since 4.1.5
*/
public class CmisSecurityContextCleanerFilter implements Filter
{
@Override
public void destroy()
{
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException
{
ContextHolder.setContext(null);
chain.doFilter(servletRequest, servletResponse);
}
@Override
public void init(FilterConfig config) throws ServletException
{
}
}
@@ -1,124 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.app.servlet;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import javax.servlet.http.HttpServletRequest;
import org.alfresco.repo.management.subsystems.AbstractChainedSubsystemTest;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.alfresco.repo.management.subsystems.DefaultChildApplicationContextManager;
import org.alfresco.repo.webdav.auth.RemoteUserMapper;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext;
/**
* @author dward
*
*/
public class DefaultRemoteUserMapperTest extends AbstractChainedSubsystemTest
{
ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
DefaultChildApplicationContextManager childApplicationContextManager;
ChildApplicationContextFactory childApplicationContextFactory;
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception
{
childApplicationContextManager = (DefaultChildApplicationContextManager) ctx.getBean("Authentication");
childApplicationContextManager.stop();
childApplicationContextManager.setProperty("chain", "external1:external");
childApplicationContextFactory = getChildApplicationContextFactory(childApplicationContextManager, "external1");
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception
{
childApplicationContextManager.destroy();
childApplicationContextManager = null;
childApplicationContextFactory = null;
}
public void testUnproxiedHeader() throws Exception
{
// Clear the proxy user name
childApplicationContextFactory.stop();
childApplicationContextFactory.setProperty("external.authentication.proxyUserName", "");
// Mock a request with a username in the header
HttpServletRequest mockRequest = mock(HttpServletRequest.class);
when(mockRequest.getHeader("X-Alfresco-Remote-User")).thenReturn("AdMiN");
assertEquals("admin", ((RemoteUserMapper) childApplicationContextFactory.getApplicationContext().getBean(
"remoteUserMapper")).getRemoteUser(mockRequest));
// Mock an unauthenticated request
when(mockRequest.getHeader("X-Alfresco-Remote-User")).thenReturn(null);
assertNull(((RemoteUserMapper) childApplicationContextFactory.getApplicationContext().getBean(
"remoteUserMapper")).getRemoteUser(mockRequest));
// Mock a remote user request
when(mockRequest.getRemoteUser()).thenReturn("ADMIN");
assertEquals("admin", ((RemoteUserMapper) childApplicationContextFactory.getApplicationContext().getBean(
"remoteUserMapper")).getRemoteUser(mockRequest));
}
public void testProxiedHeader() throws Exception
{
// Set the proxy user name
childApplicationContextFactory.stop();
childApplicationContextFactory.setProperty("external.authentication.proxyUserName", "bob");
// Mock a request with both a user and a header
HttpServletRequest mockRequest = mock(HttpServletRequest.class);
when(mockRequest.getRemoteUser()).thenReturn("bob");
when(mockRequest.getHeader("X-Alfresco-Remote-User")).thenReturn("AdMiN");
assertEquals("admin", ((RemoteUserMapper) childApplicationContextFactory.getApplicationContext().getBean(
"remoteUserMapper")).getRemoteUser(mockRequest));
// Now try header pattern matching
childApplicationContextFactory.stop();
childApplicationContextFactory.setProperty("external.authentication.userIdPattern", "abc-(.*)-999");
when(mockRequest.getHeader("X-Alfresco-Remote-User")).thenReturn("abc-AdMiN-999");
assertEquals("admin", ((RemoteUserMapper) childApplicationContextFactory.getApplicationContext().getBean(
"remoteUserMapper")).getRemoteUser(mockRequest));
// Try a request with an invalid match
when(mockRequest.getHeader("X-Alfresco-Remote-User")).thenReturn("abc-AdMiN-998");
assertNull(((RemoteUserMapper) childApplicationContextFactory.getApplicationContext().getBean(
"remoteUserMapper")).getRemoteUser(mockRequest));
// Try a request without the remote user
when(mockRequest.getRemoteUser()).thenReturn(null);
assertNull(((RemoteUserMapper) childApplicationContextFactory.getApplicationContext().getBean(
"remoteUserMapper")).getRemoteUser(mockRequest));
}
}
@@ -1093,6 +1093,8 @@ public class BrowseBean implements IContextListener, Serializable
sp.setLimit(searchLimit);
}
sp.setBulkFetchEnabled(Application.getClientConfig(FacesContext.getCurrentInstance()).isBulkFetchEnabled());
results = this.getSearchService().query(sp);
if (logger.isDebugEnabled())
logger.debug("Search results returned: " + results.length());
@@ -30,6 +30,8 @@ import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationDisallowedException;
@@ -379,6 +381,9 @@ public class LoginBean implements Serializable
// the app to continue without redirecting to the login page
Application.setCurrentUser(fc, user);
// Save the current username to cookie
AuthenticationHelper.setUsernameCookie((HttpServletRequest) fc.getExternalContext().getRequest(),(HttpServletResponse) fc.getExternalContext().getResponse(), this.username);
// Programatically retrieve the LoginOutcomeBean from JSF
LoginOutcomeBean loginOutcomeBean = (LoginOutcomeBean) fc.getApplication().createValueBinding(
"#{LoginOutcomeBean}").getValue(fc);
@@ -388,7 +393,7 @@ public class LoginBean implements Serializable
String redirectURL = loginOutcomeBean.getRedirectURL();
// ALF-10312: Validate we are redirecting within this web app
if (redirectURL != null && !redirectURL.startsWith(fc.getExternalContext().getRequestContextPath()))
if (redirectURL != null && !redirectURL.isEmpty() && !redirectURL.startsWith(fc.getExternalContext().getRequestContextPath()))
{
if (logger.isWarnEnabled())
logger.warn("Security violation. Unable to redirect to external location: " + redirectURL);
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,7 @@
*/
package org.alfresco.web.bean;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -33,6 +34,8 @@ import org.alfresco.web.app.Application;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.component.UIActionLink;
public class SpaceLinkDetailsDialog extends BaseDetailsBean implements NavigationSupport
@@ -106,7 +109,6 @@ public class SpaceLinkDetailsDialog extends BaseDetailsBean implements Navigatio
public void nextItem(ActionEvent event)
{
boolean foundNextItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -114,41 +116,16 @@ public class SpaceLinkDetailsDialog extends BaseDetailsBean implements Navigatio
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node next = null;
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupSpaceAction(next.getId(), false);
// we found a next item
foundNextItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupSpaceAction(next.getId(), false);
}
// if we did not find a next item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundNextItem == false)
if (next == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -159,7 +136,6 @@ public class SpaceLinkDetailsDialog extends BaseDetailsBean implements Navigatio
public void previousItem(ActionEvent event)
{
boolean foundPreviousItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -167,38 +143,16 @@ public class SpaceLinkDetailsDialog extends BaseDetailsBean implements Navigatio
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node previous = null;
if (nodes.size() > 1)
{
// see above
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// show details for this node
this.browseBean.setupSpaceAction(previous.getId(), false);
// we found a next item
foundPreviousItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupSpaceAction(previous.getId(), false);
}
// if we did not find a previous item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundPreviousItem == false)
if (previous == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -28,6 +28,7 @@ import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.executer.MailActionExecuter;
import org.alfresco.repo.template.I18NMessageMethod;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -168,7 +169,7 @@ public class TemplateMailHelperBean implements Serializable
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
message.setTo(to);
message.setSubject(subject);
message.setText(finalBody);
message.setText(finalBody, MailActionExecuter.isHTML(finalBody));
message.setFrom(from);
}
};
@@ -136,7 +136,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem
public boolean paste(final FacesContext fc, String viewId, final int action)
{
final ServiceRegistry serviceRegistry = getServiceRegistry();
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper();
final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getTransactionService().getRetryingTransactionHelper();
if (super.canCopyToViewId(viewId) || WORKSPACE_PASTE_VIEW_ID.equals(viewId) || FORUMS_PASTE_VIEW_ID.equals(viewId) ||
FORUM_PASTE_VIEW_ID.equals(viewId))
{
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -22,6 +22,7 @@ import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -59,6 +60,8 @@ import org.alfresco.web.bean.ml.SingleEditionBean;
import org.alfresco.web.bean.repository.MapNode;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.ReportedException;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.Utils.URLMode;
@@ -711,32 +714,12 @@ public class DocumentDetailsDialog extends BaseDetailsBean implements Navigatio
List<Node> nodes = this.browseBean.getContent();
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i=0; i<nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
getRecentNodeRefsStack().clear();
this.browseBean.setupContentAction(next.getId(), false);
break;
}
}
String currentSortColumn = this.browseBean.getContentRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getContentRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
Node next = NodeListUtils.nextItem(nodes, id);
getRecentNodeRefsStack().clear();
this.browseBean.setupContentAction(next.getId(), false);
}
}
}
@@ -754,29 +737,12 @@ public class DocumentDetailsDialog extends BaseDetailsBean implements Navigatio
List<Node> nodes = this.browseBean.getContent();
if (nodes.size() > 1)
{
// see above
for (int i=0; i<nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// prepare for showing details for this node
getRecentNodeRefsStack().clear();
this.browseBean.setupContentAction(previous.getId(), false);
break;
}
}
String currentSortColumn = this.browseBean.getContentRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getContentRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
Node previous = NodeListUtils.previousItem(nodes, id);
getRecentNodeRefsStack().clear();
this.browseBean.setupContentAction(previous.getId(), false);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,7 @@
*/
package org.alfresco.web.bean.content;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -33,6 +34,8 @@ import org.alfresco.web.app.Application;
import org.alfresco.web.bean.BaseDetailsBean;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.Utils.URLMode;
import org.alfresco.web.ui.common.component.UIActionLink;
@@ -122,31 +125,11 @@ public class DocumentLinkDetailsDialog extends BaseDetailsBean implements Naviga
List<Node> nodes = this.browseBean.getContent();
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i=0; i<nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupContentAction(next.getId(), false);
break;
}
}
String currentSortColumn = this.browseBean.getContentRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getContentRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
Node next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupContentAction(next.getId(), false);
}
}
@@ -162,28 +145,11 @@ public class DocumentLinkDetailsDialog extends BaseDetailsBean implements Naviga
List<Node> nodes = this.browseBean.getContent();
if (nodes.size() > 1)
{
// see above
for (int i=0; i<nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// prepare for showing details for this node
this.browseBean.setupContentAction(previous.getId(), false);
break;
}
}
String currentSortColumn = this.browseBean.getContentRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getContentRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
Node previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupContentAction(previous.getId(), false);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,7 @@
*/
package org.alfresco.web.bean.forums;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -34,6 +35,8 @@ import org.alfresco.web.bean.BaseDetailsBean;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.component.UIActionLink;
public class ForumDetailsDialog extends BaseDetailsBean implements NavigationSupport
@@ -123,7 +126,6 @@ public class ForumDetailsDialog extends BaseDetailsBean implements NavigationSup
public void nextItem(ActionEvent event)
{
boolean foundNextItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -131,41 +133,16 @@ public class ForumDetailsDialog extends BaseDetailsBean implements NavigationSup
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node next = null;
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupSpaceAction(next.getId(), false);
// we found a next item
foundNextItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupSpaceAction(next.getId(), false);
}
// if we did not find a next item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundNextItem == false)
if (next == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -176,7 +153,6 @@ public class ForumDetailsDialog extends BaseDetailsBean implements NavigationSup
public void previousItem(ActionEvent event)
{
boolean foundPreviousItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -184,38 +160,16 @@ public class ForumDetailsDialog extends BaseDetailsBean implements NavigationSup
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node previous = null;
if (nodes.size() > 1)
{
// see above
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// show details for this node
this.browseBean.setupSpaceAction(previous.getId(), false);
// we found a next item
foundPreviousItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupSpaceAction(previous.getId(), false);
}
// if we did not find a previous item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundPreviousItem == false)
if (previous == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,7 @@
*/
package org.alfresco.web.bean.forums;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -34,6 +35,8 @@ import org.alfresco.web.bean.BaseDetailsBean;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.component.UIActionLink;
public class ForumsDetailsDialog extends BaseDetailsBean implements NavigationSupport
@@ -123,7 +126,6 @@ public class ForumsDetailsDialog extends BaseDetailsBean implements NavigationSu
public void nextItem(ActionEvent event)
{
boolean foundNextItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -131,41 +133,16 @@ public class ForumsDetailsDialog extends BaseDetailsBean implements NavigationSu
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node next = null;
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupSpaceAction(next.getId(), false);
// we found a next item
foundNextItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupSpaceAction(next.getId(), false);
}
// if we did not find a next item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundNextItem == false)
if (next == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -176,7 +153,6 @@ public class ForumsDetailsDialog extends BaseDetailsBean implements NavigationSu
public void previousItem(ActionEvent event)
{
boolean foundPreviousItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -184,38 +160,16 @@ public class ForumsDetailsDialog extends BaseDetailsBean implements NavigationSu
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node previous = null;
if (nodes.size() > 1)
{
// see above
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// show details for this node
this.browseBean.setupSpaceAction(previous.getId(), false);
// we found a next item
foundPreviousItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupSpaceAction(previous.getId(), false);
}
// if we did not find a previous item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundPreviousItem == false)
if (previous == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,7 @@
*/
package org.alfresco.web.bean.forums;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -34,6 +35,8 @@ import org.alfresco.web.bean.BaseDetailsBean;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.component.UIActionLink;
public class TopicDetailsDialog extends BaseDetailsBean implements NavigationSupport
@@ -123,7 +126,6 @@ public class TopicDetailsDialog extends BaseDetailsBean implements NavigationSup
public void nextItem(ActionEvent event)
{
boolean foundNextItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -131,41 +133,16 @@ public class TopicDetailsDialog extends BaseDetailsBean implements NavigationSup
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node next = null;
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupSpaceAction(next.getId(), false);
// we found a next item
foundNextItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupSpaceAction(next.getId(), false);
}
// if we did not find a next item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundNextItem == false)
if (next == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -176,7 +153,6 @@ public class TopicDetailsDialog extends BaseDetailsBean implements NavigationSup
public void previousItem(ActionEvent event)
{
boolean foundPreviousItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -184,38 +160,16 @@ public class TopicDetailsDialog extends BaseDetailsBean implements NavigationSup
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node previous = null;
if (nodes.size() > 1)
{
// see above
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// show details for this node
this.browseBean.setupSpaceAction(previous.getId(), false);
// we found a next item
foundPreviousItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupSpaceAction(previous.getId(), false);
}
// if we did not find a previous item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundPreviousItem == false)
if (previous == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -1,23 +1,24 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.bean.preview;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -31,6 +32,8 @@ import org.alfresco.web.app.Application;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.component.UIActionLink;
/**
@@ -100,31 +103,11 @@ public class DocumentPreviewBean extends BasePreviewBean implements NavigationSu
List<Node> nodes = this.browseBean.getContent();
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupContentAction(next.getId(), false);
break;
}
}
String currentSortColumn = this.browseBean.getContentRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getContentRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
Node next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupContentAction(next.getId(), false);
}
}
}
@@ -139,28 +122,11 @@ public class DocumentPreviewBean extends BasePreviewBean implements NavigationSu
List<Node> nodes = this.browseBean.getContent();
if (nodes.size() > 1)
{
// see above
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// prepare for showing details for this node
this.browseBean.setupContentAction(previous.getId(), false);
break;
}
}
String currentSortColumn = this.browseBean.getContentRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getContentRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
Node previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupContentAction(previous.getId(), false);
}
}
}
@@ -1,23 +1,24 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.bean.preview;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -31,6 +32,8 @@ import org.alfresco.web.app.Application;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.component.UIActionLink;
/**
@@ -89,7 +92,6 @@ public class SpacePreviewBean extends BasePreviewBean implements NavigationSuppo
public void nextItem(ActionEvent event)
{
boolean foundNextItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -97,41 +99,16 @@ public class SpacePreviewBean extends BasePreviewBean implements NavigationSuppo
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node next = null;
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupSpaceAction(next.getId(), false);
// we found a next item
foundNextItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupSpaceAction(next.getId(), false);
}
// if we did not find a next item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundNextItem == false)
if (next == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -142,7 +119,6 @@ public class SpacePreviewBean extends BasePreviewBean implements NavigationSuppo
public void previousItem(ActionEvent event)
{
boolean foundPreviousItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -150,38 +126,16 @@ public class SpacePreviewBean extends BasePreviewBean implements NavigationSuppo
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node previous = null;
if (nodes.size() > 1)
{
// see above
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// show details for this node
this.browseBean.setupSpaceAction(previous.getId(), false);
// we found a next item
foundPreviousItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupSpaceAction(previous.getId(), false);
}
// if we did not find a previous item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundPreviousItem == false)
if (previous == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -1,4 +1,4 @@
/*
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
@@ -14,184 +14,184 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.bean.repository;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.bean.repository;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.SessionUser;
import org.alfresco.repo.configuration.ConfigurableService;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.SessionUser;
import org.alfresco.repo.configuration.ConfigurableService;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.jsf.FacesContextUtils;
/**
* Bean that represents the currently logged in user
*
* @author gavinc
*/
public final class User implements SessionUser
{
private static final long serialVersionUID = -90577901805847829L;
private String companyRootId;
private String homeSpaceId;
private String userName;
private String ticket;
private NodeRef person;
private String fullName = null;
private Boolean administrator = null;
private Preferences preferences = null;
/**
* Constructor
*
* @param userName constructor for the user
*/
public User(String userName, String ticket, NodeRef person)
{
if (userName == null || ticket == null || person == null)
{
throw new IllegalArgumentException("All user details are mandatory!");
}
this.userName = userName;
this.ticket = ticket;
this.person = person;
}
/**
* Forces a clear of any cached or calcluated values
*/
public void reset()
{
this.fullName = null;
this.administrator = null;
this.preferences = null;
}
/**
* @return The user name
*/
public String getUserName()
{
return this.userName;
}
/**
* Return the full name of the Person this User represents
*
* @param service NodeService to use
*
* @return The full name
*/
public String getFullName(NodeService service)
{
if (this.fullName == null)
{
String firstName = (String)service.getProperty(this.person, ContentModel.PROP_FIRSTNAME);
String lastName = (String)service.getProperty(this.person, ContentModel.PROP_LASTNAME);
this.fullName = (firstName != null ? firstName : "") + ' ' + (lastName != null ? lastName : "");
}
return this.fullName;
}
/**
* @return Retrieves the user's home space (this may be the id of the company home space)
*/
public String getHomeSpaceId()
{
return this.homeSpaceId;
}
/**
* @param homeSpaceId Sets the id of the users home space
*/
public void setHomeSpaceId(String homeSpaceId)
{
this.homeSpaceId = homeSpaceId;
}
/**
* @return Retrieves the company home space
*/
public String getCompanyRootId()
{
return this.companyRootId;
}
/**
* @param companyRootId Sets the id of the company home space
*/
public void setCompanyRootId(String companyRootId)
{
this.companyRootId = companyRootId;
}
/**
* @return Returns the ticket.
*/
public String getTicket()
{
return this.ticket;
}
/**
* @return Returns the person NodeRef
*/
public NodeRef getPerson()
{
return this.person;
}
/**
* @return If the current user has Admin Authority
*/
public boolean isAdmin()
{
if (administrator == null)
{
administrator = Repository.getServiceRegistry(FacesContext.getCurrentInstance())
.getAuthorityService().hasAdminAuthority();
}
return administrator;
}
/**
* @return The Preferences for the User
*/
/**
* Bean that represents the currently logged in user
*
* @author gavinc
*/
public final class User implements SessionUser
{
private static final long serialVersionUID = -90577901805847829L;
private String companyRootId;
private String homeSpaceId;
private String userName;
private String ticket;
private NodeRef person;
private String fullName = null;
private Boolean administrator = null;
private Preferences preferences = null;
/**
* Constructor
*
* @param userName constructor for the user
*/
public User(String userName, String ticket, NodeRef person)
{
if (userName == null || ticket == null || person == null)
{
throw new IllegalArgumentException("All user details are mandatory!");
}
this.userName = userName;
this.ticket = ticket;
this.person = person;
}
/**
* Forces a clear of any cached or calcluated values
*/
public void reset()
{
this.fullName = null;
this.administrator = null;
this.preferences = null;
}
/**
* @return The user name
*/
public String getUserName()
{
return this.userName;
}
/**
* Return the full name of the Person this User represents
*
* @param service NodeService to use
*
* @return The full name
*/
public String getFullName(NodeService service)
{
if (this.fullName == null)
{
String firstName = (String)service.getProperty(this.person, ContentModel.PROP_FIRSTNAME);
String lastName = (String)service.getProperty(this.person, ContentModel.PROP_LASTNAME);
this.fullName = (firstName != null ? firstName : "") + ' ' + (lastName != null ? lastName : "");
}
return this.fullName;
}
/**
* @return Retrieves the user's home space (this may be the id of the company home space)
*/
public String getHomeSpaceId()
{
return this.homeSpaceId;
}
/**
* @param homeSpaceId Sets the id of the users home space
*/
public void setHomeSpaceId(String homeSpaceId)
{
this.homeSpaceId = homeSpaceId;
}
/**
* @return Retrieves the company home space
*/
public String getCompanyRootId()
{
return this.companyRootId;
}
/**
* @param companyRootId Sets the id of the company home space
*/
public void setCompanyRootId(String companyRootId)
{
this.companyRootId = companyRootId;
}
/**
* @return Returns the ticket.
*/
public String getTicket()
{
return this.ticket;
}
/**
* @return Returns the person NodeRef
*/
public NodeRef getPerson()
{
return this.person;
}
/**
* @return If the current user has Admin Authority
*/
public boolean isAdmin()
{
if (administrator == null)
{
administrator = Repository.getServiceRegistry(FacesContext.getCurrentInstance())
.getAuthorityService().hasAdminAuthority();
}
return administrator;
}
/**
* @return The Preferences for the User
*/
Preferences getPreferences(FacesContext fc)
{
if (this.preferences == null)
{
{
if (this.preferences == null)
{
this.preferences = new Preferences(getUserPreferencesRef(
FacesContextUtils.getRequiredWebApplicationContext(fc)));
}
return this.preferences;
}
/**
}
return this.preferences;
}
/**
* @return The Preferences for the User
*/
Preferences getPreferences(ServletContext sc)
@@ -205,88 +205,87 @@ public final class User implements SessionUser
}
/**
* Get or create the node used to store user preferences.
* Utilises the 'configurable' aspect on the Person linked to this user.
*/
* Get or create the node used to store user preferences.
* Utilises the 'configurable' aspect on the Person linked to this user.
*/
synchronized NodeRef getUserPreferencesRef(WebApplicationContext context)
{
final ServiceRegistry registry = (ServiceRegistry) context.getBean("ServiceRegistry");
final NodeService nodeService = registry.getNodeService();
final SearchService searchService = registry.getSearchService();
final NamespaceService namespaceService = registry.getNamespaceService();
final TransactionService txService = registry.getTransactionService();
final ConfigurableService configurableService = (ConfigurableService) context.getBean("ConfigurableService");
RetryingTransactionHelper txnHelper = registry.getRetryingTransactionHelper();
return txnHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
{
public NodeRef execute() throws Throwable
{
NodeRef prefRef = null;
NodeRef person = getPerson();
if (nodeService.hasAspect(person, ApplicationModel.ASPECT_CONFIGURABLE) == false)
{
// if the repository is in read-only mode just return null
if (txService.isReadOnly())
{
return null;
}
else
{
// create the configuration folder for this Person node
configurableService.makeConfigurable(person);
}
}
// target of the assoc is the configurations folder ref
NodeRef configRef = configurableService.getConfigurationFolder(person);
if (configRef == null)
{
throw new IllegalStateException("Unable to find associated 'configurations' folder for node: "
+ person);
}
String xpath = NamespaceService.APP_MODEL_PREFIX + ":" + "preferences";
List<NodeRef> nodes = searchService.selectNodes(configRef, xpath, null, namespaceService, false);
if (nodes.size() == 1)
{
prefRef = nodes.get(0);
}
else
{
// create the preferences Node for this user (if repo is not read-only)
if (txService.isReadOnly() == false)
{
final ServiceRegistry registry = (ServiceRegistry) context.getBean("ServiceRegistry");
final NodeService nodeService = registry.getNodeService();
final SearchService searchService = registry.getSearchService();
final NamespaceService namespaceService = registry.getNamespaceService();
final TransactionService txService = registry.getTransactionService();
final ConfigurableService configurableService = (ConfigurableService) context.getBean("ConfigurableService");
RetryingTransactionHelper txnHelper = registry.getTransactionService().getRetryingTransactionHelper();
return txnHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
{
public NodeRef execute() throws Throwable
{
NodeRef prefRef = null;
NodeRef person = getPerson();
if (nodeService.hasAspect(person, ApplicationModel.ASPECT_CONFIGURABLE) == false)
{
// if the repository is in read-only mode just return null
if (txService.isReadOnly())
{
ChildAssociationRef childRef = nodeService.createNode(configRef,
ContentModel.ASSOC_CONTAINS, QName.createQName(
NamespaceService.APP_MODEL_1_0_URI, "preferences"),
ContentModel.TYPE_CMOBJECT);
prefRef = childRef.getChildRef();
}
}
return prefRef;
}
});
}
/**
* Returns the full name of the user represented by the given NodeRef
*
* @param nodeService The node service instance
* @param user The user to get the full name for
* @return The full name
*/
public static String getFullName(NodeService nodeService, NodeRef user)
{
Map<QName, Serializable> props = nodeService.getProperties(user);
String firstName = (String)props.get(ContentModel.PROP_FIRSTNAME);
String lastName = (String)props.get(ContentModel.PROP_LASTNAME);
String fullName = firstName + ((lastName != null && lastName.length() > 0) ? " " + lastName : "");
return fullName;
}
return null;
}
else
{
// create the configuration folder for this Person node
configurableService.makeConfigurable(person);
}
}
// target of the assoc is the configurations folder ref
NodeRef configRef = configurableService.getConfigurationFolder(person);
if (configRef == null)
{
throw new IllegalStateException("Unable to find associated 'configurations' folder for node: "
+ person);
}
String xpath = NamespaceService.APP_MODEL_PREFIX + ":" + "preferences";
List<NodeRef> nodes = searchService.selectNodes(configRef, xpath, null, namespaceService, false);
if (nodes.size() == 1)
{
prefRef = nodes.get(0);
}
else
{
// create the preferences Node for this user (if repo is not read-only)
if (txService.isReadOnly() == false)
{
ChildAssociationRef childRef = nodeService.createNode(configRef,
ContentModel.ASSOC_CONTAINS, QName.createQName(
NamespaceService.APP_MODEL_1_0_URI, "preferences"),
ContentModel.TYPE_CMOBJECT);
prefRef = childRef.getChildRef();
}
}
return prefRef;
}
});
}
/**
* Returns the full name of the user represented by the given NodeRef
*
* @param nodeService The node service instance
* @param user The user to get the full name for
* @return The full name
*/
public static String getFullName(NodeService nodeService, NodeRef user)
{
Map<QName, Serializable> props = nodeService.getProperties(user);
String firstName = (String)props.get(ContentModel.PROP_FIRSTNAME);
String lastName = (String)props.get(ContentModel.PROP_LASTNAME);
String fullName = firstName + ((lastName != null && lastName.length() > 0) ? " " + lastName : "");
return fullName;
}
/**
* Returns the full name of the user plus their userid in the form [id]
@@ -313,4 +312,4 @@ public final class User implements SessionUser
return nameAndId.toString();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -20,6 +20,7 @@ package org.alfresco.web.bean.spaces;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -39,6 +40,8 @@ import org.alfresco.web.bean.TemplateSupportBean;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.Utils.URLMode;
import org.alfresco.web.ui.common.component.UIActionLink;
@@ -165,49 +168,23 @@ public class SpaceDetailsDialog extends BaseDetailsBean implements NavigationSup
*/
public void nextItem(ActionEvent event)
{
boolean foundNextItem = false;
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
if (id != null && id.length() != 0)
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node next = null;
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i=0; i<nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupSpaceAction(next.getId(), false);
// we found a next item
foundNextItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupSpaceAction(next.getId(), false);
}
// if we did not find a next item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundNextItem == false)
if (next == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -220,46 +197,23 @@ public class SpaceDetailsDialog extends BaseDetailsBean implements NavigationSup
*/
public void previousItem(ActionEvent event)
{
boolean foundPreviousItem = false;
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
if (id != null && id.length() != 0)
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node previous = null;
if (nodes.size() > 1)
{
// see above
for (int i=0; i<nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// show details for this node
this.browseBean.setupSpaceAction(previous.getId(), false);
// we found a next item
foundPreviousItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupSpaceAction(previous.getId(), false);
}
// if we did not find a previous item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundPreviousItem == false)
if (previous == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,7 @@
*/
package org.alfresco.web.bean.wcm;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -29,7 +30,10 @@ import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.web.bean.dialog.BaseDialogBean;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
@@ -194,31 +198,26 @@ public abstract class AVMDetailsBean extends BaseDialogBean implements Navigatio
List<AVMNode> nodes = getNodes();
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the item has changed etc.
for (int i=0; i<nodes.size(); i++)
String currentSortColumn;
boolean currentSortDescending;
if (nodes.get(0).isFile())
{
if (path.equals(nodes.get(i).get("id")) == true)
{
AVMNode next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.avmBrowseBean.setupContentAction(next.getPath(), false);
break;
}
currentSortColumn = this.avmBrowseBean.getFilesRichList().getCurrentSortColumn();
currentSortDescending = this.avmBrowseBean.getFilesRichList().isCurrentSortDescending();
}
else
{
currentSortColumn = this.avmBrowseBean.getFoldersRichList().getCurrentSortColumn();
currentSortDescending = this.avmBrowseBean.getFoldersRichList().isCurrentSortDescending();
}
if (currentSortColumn != null)
{
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
}
AVMNode next = (AVMNode) NodeListUtils.nextItem(nodes, path);
this.avmBrowseBean.setupContentAction(next.getPath(), false);
}
}
}
@@ -237,28 +236,26 @@ public abstract class AVMDetailsBean extends BaseDialogBean implements Navigatio
List<AVMNode> nodes = getNodes();
if (nodes.size() > 1)
{
// see above
for (int i=0; i<nodes.size(); i++)
String currentSortColumn;
boolean currentSortDescending;
if (nodes.get(0).isFile())
{
if (path.equals(nodes.get(i).get("id")) == true)
{
AVMNode previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// prepare for showing details for this node
this.avmBrowseBean.setupContentAction(previous.getPath(), false);
break;
}
currentSortColumn = this.avmBrowseBean.getFilesRichList().getCurrentSortColumn();
currentSortDescending = this.avmBrowseBean.getFilesRichList().isCurrentSortDescending();
}
else
{
currentSortColumn = this.avmBrowseBean.getFoldersRichList().getCurrentSortColumn();
currentSortDescending = this.avmBrowseBean.getFoldersRichList().isCurrentSortDescending();
}
if (currentSortColumn != null)
{
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
}
AVMNode previous = (AVMNode) NodeListUtils.previousItem(nodes, path);
this.avmBrowseBean.setupContentAction(previous.getPath(), false);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -18,6 +18,7 @@
*/
package org.alfresco.web.bean.wcm;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -34,6 +35,8 @@ import org.alfresco.web.bean.BaseDetailsBean;
import org.alfresco.web.bean.dialog.NavigationSupport;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.NodeListUtils;
import org.alfresco.web.ui.common.NodePropertyComparator;
import org.alfresco.web.ui.common.component.UIActionLink;
public class WebSiteDetailsDialog extends BaseDetailsBean implements NavigationSupport
@@ -115,7 +118,6 @@ public class WebSiteDetailsDialog extends BaseDetailsBean implements NavigationS
public void nextItem(ActionEvent event)
{
boolean foundNextItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -123,41 +125,16 @@ public class WebSiteDetailsDialog extends BaseDetailsBean implements NavigationS
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node next = null;
if (nodes.size() > 1)
{
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node next;
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
// prepare for showing details for this node
this.browseBean.setupSpaceAction(next.getId(), false);
// we found a next item
foundNextItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
next = NodeListUtils.nextItem(nodes, id);
this.browseBean.setupSpaceAction(next.getId(), false);
}
// if we did not find a next item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundNextItem == false)
if (next == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -168,7 +145,6 @@ public class WebSiteDetailsDialog extends BaseDetailsBean implements NavigationS
public void previousItem(ActionEvent event)
{
boolean foundPreviousItem = false;
UIActionLink link = (UIActionLink) event.getComponent();
Map<String, String> params = link.getParameterMap();
String id = params.get("id");
@@ -176,38 +152,16 @@ public class WebSiteDetailsDialog extends BaseDetailsBean implements NavigationS
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
Node previous = null;
if (nodes.size() > 1)
{
// see above
for (int i = 0; i < nodes.size(); i++)
{
if (id.equals(nodes.get(i).getId()) == true)
{
Node previous;
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
// show details for this node
this.browseBean.setupSpaceAction(previous.getId(), false);
// we found a next item
foundPreviousItem = true;
}
}
String currentSortColumn = this.browseBean.getSpacesRichList().getCurrentSortColumn();
boolean currentSortDescending = this.browseBean.getSpacesRichList().isCurrentSortDescending();
Collections.sort(nodes, new NodePropertyComparator(currentSortColumn, !currentSortDescending));
previous = NodeListUtils.previousItem(nodes, id);
this.browseBean.setupSpaceAction(previous.getId(), false);
}
// if we did not find a previous item make sure the current node is
// in the dispatch context otherwise the details screen will go back
// to the default one.
if (foundPreviousItem == false)
if (previous == null)
{
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
@@ -34,7 +34,6 @@ import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import javax.transaction.UserTransaction;
import org.springframework.extensions.config.ConfigElement;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.publishing.PublishingEventHelper;
@@ -68,6 +67,7 @@ import org.alfresco.web.ui.common.component.UIActionLink;
import org.alfresco.web.ui.common.component.data.UIRichList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.config.ConfigElement;
/**
* Bean implementation for the Start Workflow Wizard.
@@ -85,6 +85,7 @@ public class StartWorkflowWizard extends BaseWizardBean
transient private Map<String, WorkflowDefinition> workflows;
protected List<String> wcmWorkflows;
protected List<String> excludedWorkflows;
protected List<String> invitationWorkflows;
protected List<String> publishingWorkflows;
@@ -574,6 +575,7 @@ public class StartWorkflowWizard extends BaseWizardBean
List<String> configuredWcmWorkflows = this.getWCMWorkflowNames();
List<String> configuredInvitationWorkflows = this.getInvitationServiceWorkflowNames();
List<String> publishingWorkflows = this.getPublishingWorkflowNames();
List<String> excludedWorkflows = this.getExcludedWorkflows();
List<WorkflowDefinition> workflowDefs = this.getWorkflowService().getDefinitions();
for (WorkflowDefinition workflowDef : workflowDefs)
@@ -582,7 +584,8 @@ public class StartWorkflowWizard extends BaseWizardBean
if (configuredWcmWorkflows.contains(name) == false &&
configuredInvitationWorkflows.contains(name) == false &&
publishingWorkflows.contains(name) == false)
publishingWorkflows.contains(name) == false &&
excludedWorkflows.contains(name) == false)
{
// add the workflow if it is not a WCM specific workflow
String label = workflowDef.title;
@@ -789,6 +792,36 @@ public class StartWorkflowWizard extends BaseWizardBean
return wcmWorkflows;
}
/**
* Get the Names of globally excluded workflow-names.
*
* @return The names of the workflows to exclude.
*/
protected List<String> getExcludedWorkflows()
{
if ((excludedWorkflows == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
{
FacesContext fc = FacesContext.getCurrentInstance();
ConfigElement config = Application.getConfigService(fc).getGlobalConfig().getConfigElement("excluded-workflows");
if (config != null)
{
StringTokenizer t = new StringTokenizer(config.getValue().trim(), ", ");
excludedWorkflows = new ArrayList<String>(t.countTokens());
while (t.hasMoreTokens())
{
String wfName = t.nextToken();
excludedWorkflows.add(wfName);
}
}
else
{
excludedWorkflows = Collections.emptyList();
}
}
return excludedWorkflows;
}
/**
* Get the Names of the Invitation Service Workflows
*
@@ -11,6 +11,7 @@ import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.TransientMapNode;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Wrapper around a {@link WorkflowTask} to allow it to be approached as a {@link Node}.
@@ -68,6 +69,16 @@ public class WorkflowTaskNode extends TransientMapNode {
// add the task itself as a property
propertyWrapper.put("workflowTask", workflowTask);
}
// Add an additional property, containing a human-friendly representation of the priority
Integer priority = (Integer) workflowTask.getProperties().get(WorkflowModel.PROP_PRIORITY);
String priorityMessage = "";
if (priority != null)
{
priorityMessage = I18NUtil.getMessage(getPriorityMessageKey(priority), I18NUtil.getLocale());
}
propertyWrapper.put("priorityMessage", priorityMessage);
}
@Override
@@ -112,4 +123,9 @@ public class WorkflowTaskNode extends TransientMapNode {
return super.put(QName.resolveToQNameString(WorkflowTaskNode.this.getNamespacePrefixResolver(), key.toString()), value);
}
}
protected String getPriorityMessageKey(int priority)
{
return "listconstraint.bpm_allowedPriority." + priority;
}
}
@@ -86,6 +86,7 @@ public class ClientConfigElement extends ConfigElementAdapter
private int pickerSearchMinimum = 2;
private boolean checkContextAgainstPath = false;
private boolean allowUserScriptExecute = false;
private boolean isBulkFetchEnabled = true;
/**
@@ -963,4 +964,21 @@ public class ClientConfigElement extends ConfigElementAdapter
{
this.allowUserScriptExecute = allowUserScriptExecute;
}
/**
* @return true if bulk fetch is enabled
*/
public boolean isBulkFetchEnabled()
{
return isBulkFetchEnabled;
}
/**
* @param isBulkFetchEnabled
*/
/*package*/ void setBulkFetchEnabled(boolean isBulkFetchEnabled)
{
this.isBulkFetchEnabled = isBulkFetchEnabled;
}
}
@@ -43,6 +43,7 @@ public class ClientElementReader implements ConfigElementReader
public static final String ELEMENT_SEARCHMINIMUM = "search-minimum";
public static final String ELEMENT_SEARCHANDTERMS = "search-and-terms";
public static final String ELEMENT_SEARCHMAXRESULTS = "search-max-results";
public static final String ELEMENT_BULKFETCHENABLED = "bulk-fetch-enabled";
public static final String ELEMENT_SELECTORSSEARCHMAXRESULTS = "selectors-search-max-results";
public static final String ELEMENT_INVITESEARCHMAXRESULTS = "invite-users-max-results";
public static final String ELEMENT_TASKSCOMPLETEDMAXRESULTS = "tasks-completed-max-results";
@@ -141,6 +142,13 @@ public class ClientElementReader implements ConfigElementReader
configElement.setSearchMaxResults(Integer.parseInt(searchMaxResults.getTextTrim()));
}
// get the search max results size
Element isBulkFetchEnabled = element.element(ELEMENT_BULKFETCHENABLED);
if (isBulkFetchEnabled != null)
{
configElement.setBulkFetchEnabled(Boolean.parseBoolean(isBulkFetchEnabled.getTextTrim()));
}
// get the selectors search max results size
Element selectorsSearchMaxResults = element.element(ELEMENT_SELECTORSSEARCHMAXRESULTS);
if (selectorsSearchMaxResults != null)
File diff suppressed because it is too large Load Diff
@@ -1,295 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.forms;
import java.io.Serializable;
import java.util.Calendar;
import java.util.HashMap;
import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.XMLUtil;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.TestWithUserUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shale.test.mock.MockExternalContext;
import org.apache.shale.test.mock.MockFacesContext;
import org.apache.shale.test.mock.MockHttpServletRequest;
import org.apache.shale.test.mock.MockHttpServletResponse;
import org.apache.shale.test.mock.MockServletContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.w3c.dom.Document;
/**
* JUnit tests to exercise parts of the forms codebase
*
* @author ariel backenroth
*/
public class FormsTest
extends BaseSpringTest
{
/////////////////////////////////////////////////////////////////////////////
private static class MockForm
extends FormImpl
{
MockForm(final NodeRef folderNodeRef,
final FormsService formsService)
{
super(folderNodeRef, formsService);
}
public void setOutputPathPattern(final String opp)
{
final NodeService nodeService = this.getServiceRegistry().getNodeService();
nodeService.setProperty(this.getNodeRef(), WCMAppModel.PROP_OUTPUT_PATH_PATTERN, opp);
}
}
/////////////////////////////////////////////////////////////////////////////
private final static Log LOGGER = LogFactory.getLog(FormsTest.class);
private final static String WEB_CLIENT_APPLICATION_CONTEXT =
"classpath:alfresco/web-client-application-context.xml";
private NodeService nodeService;
private FormsService formsService;
private MockForm mockForm;
protected void onSetUpInTransaction()
throws Exception
{
System.err.println("onSetUpInTransaction");
super.onSetUpInTransaction();
this.nodeService = (NodeService)super.applicationContext.getBean("dbNodeService");
assertNotNull(this.nodeService);
final FileFolderService fileFolderService = (FileFolderService)
super.applicationContext.getBean("fileFolderService");
assertNotNull(fileFolderService);
this.formsService = (FormsService)super.applicationContext.getBean("FormsService");
assertNotNull(this.formsService);
final MutableAuthenticationService authenticationService = (MutableAuthenticationService)
applicationContext.getBean("authenticationService");
authenticationService.clearCurrentSecurityContext();
final MutableAuthenticationDao authenticationDAO = (MutableAuthenticationDao)
applicationContext.getBean("authenticationDao");
// Create a workspace that contains the 'live' nodes
final StoreRef testStoreRef = this.nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE,
"Test_" + System.currentTimeMillis());
// Get a reference to the root node
final NodeRef rootNodeRef = this.nodeService.getRootNode(testStoreRef);
// Create an authenticate the user
if(!authenticationDAO.userExists(AuthenticationUtil.getAdminUserName()))
{
authenticationService.createAuthentication(AuthenticationUtil.getAdminUserName(), "admin".toCharArray());
}
TestWithUserUtils.authenticateUser(AuthenticationUtil.getAdminUserName(),
"admin",
rootNodeRef,
authenticationService);
// set up a faces context
final MockExternalContext ec = new MockExternalContext(new MockServletContext(),
new MockHttpServletRequest(),
new MockHttpServletResponse());
final StaticWebApplicationContext ac = new StaticWebApplicationContext();
ac.setParent(this.applicationContext);
this.applicationContext = ac;
ec.getApplicationMap().put(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
this.applicationContext);
new MockFacesContext(ec);
final FileInfo folderInfo =
fileFolderService.create(rootNodeRef,
"test_form",
WCMAppModel.TYPE_FORMFOLDER);
final HashMap<QName, Serializable> props = new HashMap<QName, Serializable>();
this.nodeService.addAspect(folderInfo.getNodeRef(),
WCMAppModel.ASPECT_FORM,
props);
this.mockForm = new MockForm(folderInfo.getNodeRef(), this.formsService);
}
@Override
protected String[] getConfigLocations()
{
return (String[])ArrayUtils.add(super.getConfigLocations(),
WEB_CLIENT_APPLICATION_CONTEXT);
}
@Override
protected ConfigurableApplicationContext loadContext(Object key)
throws Exception
{
return new ClassPathXmlApplicationContext((String[])key);
}
public void testOutputPathPatternForFormInstanceData()
throws Exception
{
class OutputPathPatternTest
{
public final String expected;
public final String pattern;
public final Document xml;
public final String name;
public final String parentAVMPath;
public final String webapp;
public OutputPathPatternTest(final String expected,
final String pattern,
final Document xml,
final String name,
final String parentAVMPath,
final String webapp)
{
this.expected = expected;
this.pattern = pattern;
this.xml = xml;
this.name = name;
this.parentAVMPath = parentAVMPath;
this.webapp = webapp;
}
}
final OutputPathPatternTest[] opps = new OutputPathPatternTest[] {
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/dir/foo.xml",
"${name}.xml",
XMLUtil.parse("<foo/>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/foo.xml",
"/${name}.xml",
XMLUtil.parse("<foo/>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/foo.xml",
"/${webapp}/${name}.xml",
XMLUtil.parse("<foo/>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/foo.xml",
"/${webapp}/${name}.xml",
XMLUtil.parse("<foo/>"),
"foo",
"avmstore:/www/avm_webapps/another_webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/dir1/dir2/foo.xml",
"/${webapp}/${cwd}/${name}.xml",
XMLUtil.parse("<foo/>"),
"foo",
"avmstore:/www/avm_webapps/another_webapp/dir1/dir2",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/dir/" + Calendar.getInstance().get(Calendar.YEAR) + "_foo.xml",
"${date?string('yyyy')}_${name}.xml",
XMLUtil.parse("<foo/>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/dir/foo.xml",
"${xml.root_tag.name}.xml",
XMLUtil.parse("<root_tag><name>foo</name></root_tag>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/dir/07.xml",
"${xml.root_tag.date?date('yyyy-MM-dd')?string('MM')}.xml",
XMLUtil.parse("<root_tag><date>1776-07-04</date></root_tag>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/dir/foo.xml",
"${xml['foons:root_tag/foons:name']}.xml",
XMLUtil.parse("<foons:root_tag xmlns:foons='bar'><foons:name>foo</foons:name></foons:root_tag>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/dir/foo.xml",
"${xml[\"/*[name()='foons:root_tag']/*[name()='foons:name']\"]}.xml",
XMLUtil.parse("<foons:root_tag xmlns:foons='bar'><foons:name>foo</foons:name></foons:root_tag>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest("avmstore:/www/avm_webapps/webapp/dir/foo.xml",
"${xml['/foons:root_tag/foons:name']}.xml",
XMLUtil.parse("<foons:root_tag xmlns:foons='bar'><foons:name>foo</foons:name></foons:root_tag>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp"),
new OutputPathPatternTest(null,
"${xml.root_tag.name}",
XMLUtil.parse("<foons:root_tag xmlns:foons='bar'><foons:name>foo</foons:name></foons:root_tag>"),
"foo",
"avmstore:/www/avm_webapps/webapp/dir",
"webapp")
};
for (final OutputPathPatternTest oppt : opps)
{
this.mockForm.setOutputPathPattern(oppt.pattern);
if (oppt.expected == null)
{
try
{
this.mockForm.getOutputPathForFormInstanceData(oppt.xml,
oppt.name,
oppt.parentAVMPath,
oppt.webapp);
fail("expected pattern " + oppt.pattern + " to fail");
}
catch (Exception e)
{
// expected failure
}
}
else
{
assertEquals(oppt.pattern + " failed",
oppt.expected,
this.mockForm.getOutputPathForFormInstanceData(oppt.xml,
oppt.name,
oppt.parentAVMPath,
oppt.webapp));
}
}
}
}
@@ -1,143 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.forms;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import junit.framework.TestCase;
import org.alfresco.util.XMLUtil;
/**
* Simple XMLUtil test
*/
public class XMLUtilTest extends TestCase
{
public static final String SOME_XML =
" <model name='test1:testModelOne' xmlns='http://www.alfresco.org/model/dictionary/1.0'>" +
" <description>Test model one</description>" +
" <author>Alfresco</author>" +
" <published>2008-01-01</published>" +
" <version>1.0</version>" +
" <imports>" +
" <import uri='http://www.alfresco.org/model/dictionary/1.0' prefix='d'/>" +
" </imports>" +
" <namespaces>" +
" <namespace uri='http://www.alfresco.org/test/testmodel1/1.0' prefix='test1'/>" +
" </namespaces>" +
" <types>" +
" <type name='test1:base'>" +
" <title>Base</title>" +
" <description>The Base Type</description>" +
" <properties>" +
" <property name='test1:prop1'>" +
" <type>d:text</type>" +
" </property>" +
" </properties>" +
" </type>" +
" </types>" +
" </model>";
private final static int threadCount = 5;
private final static int loopCount = 50;
private final static int randomNextInt = 100;
private Map<String, Throwable> errors = new HashMap<String, Throwable>();
protected void setUp() throws Exception
{
}
// https://issues.alfresco.com/browse/ETWOONE-241
public void testConcurrentParse()
{
ThreadGroup threadGroup = new ThreadGroup(getName());
Thread[] threads = new Thread[threadCount];
for (int i = 0; i < threadCount; i++)
{
threads[i] = new Thread(threadGroup, new TestRun(""+i), String.format("XMLUtilTest-%02d", i));
threads[i].start();
}
// join each thread so that we wait for them all to finish
for (int i = 0; i < threads.length; i++)
{
try
{
threads[i].join();
}
catch (InterruptedException e)
{
// ignore
}
}
if (errors.size() != 0)
{
fail();
}
}
class TestRun extends Thread
{
private String arg;
public TestRun(String arg)
{
this.arg = arg;
}
public String getArg()
{
return arg;
}
public void run()
{
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < loopCount; i++)
{
try
{
XMLUtil.parse(SOME_XML); // ignore returned doc
}
catch (Throwable t)
{
t.printStackTrace();
errors.put(arg, t);
break;
}
// random delay ...
if (randomNextInt != 0)
{
int msecs = random.nextInt(randomNextInt);
try {Thread.sleep(msecs);} catch (Exception exception){};
}
}
}
}
}
@@ -1,679 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.forms.xforms;
import java.io.*;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.Vector;
import java.util.ResourceBundle;
import junit.framework.AssertionFailedError;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.util.BaseTest;
import org.alfresco.util.XMLUtil;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.chiba.xml.ns.NamespaceConstants;
import org.chiba.xml.events.XFormsEventNames;
import org.chiba.xml.events.XMLEvent;
import org.chiba.xml.xforms.ChibaBean;
import org.chiba.xml.xforms.exception.XFormsException;
import org.chiba.xml.xforms.XFormsElement;
import org.chiba.xml.events.DOMEventNames;
import org.w3c.dom.*;
import org.w3c.dom.events.*;
import org.xml.sax.*;
/**
* JUnit tests to exercise the the schema to xforms converter
*
* @author ariel backenroth
*/
public class Schema2XFormsTest
extends BaseTest
{
private final static Log LOGGER = LogFactory.getLog(Schema2XFormsTest.class);
public void testOneStringTestWithEmptyInstanceDocument()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/one-string-test.xsd");
final Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "one-string-test");
this.runXForm(xformsDocument);
final JXPathContext xpathContext = JXPathContext.newContext(xformsDocument);
Pointer pointer = xpathContext.getPointer("//*[@id='input_0']");
assertNotNull(pointer);
String s = ((Element)pointer.getNode()).getAttributeNS(NamespaceConstants.XFORMS_NS, "bind");
assertNotNull(s);
pointer = xpathContext.getPointer("//*[@id='" + s + "']");
assertNotNull(pointer);
assertEquals("true()", ((Element)pointer.getNode()).getAttributeNS(NamespaceConstants.XFORMS_NS, "required"));
pointer = xpathContext.getPointer("//" + NamespaceConstants.XFORMS_PREFIX + ":instance[@id='instance_0']/one-string-test/string");
assertNotNull(pointer);
assertEquals("default-value", ((Element)pointer.getNode()).getTextContent());
}
public void testOneStringTestWithInstanceDocument()
throws Exception
{
final Document instanceDocument = XMLUtil.parse("<one-string-test><string>test</string></one-string-test>");
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/one-string-test.xsd");
final Document xformsDocument = Schema2XFormsTest.buildXForm(instanceDocument, schemaDocument, "one-string-test");
this.runXForm(xformsDocument);
final JXPathContext xpathContext = JXPathContext.newContext(xformsDocument);
Pointer pointer = xpathContext.getPointer("//*[@id='input_0']");
assertNotNull(pointer);
String s = ((Element)pointer.getNode()).getAttributeNS(NamespaceConstants.XFORMS_NS, "bind");
pointer = xpathContext.getPointer("//*[@id='" + s + "']");
assertNotNull(pointer);
assertEquals("true()", ((Element)pointer.getNode()).getAttributeNS(NamespaceConstants.XFORMS_NS, "required"));
pointer = xpathContext.getPointer("//" + NamespaceConstants.XFORMS_PREFIX + ":instance[@id='instance_0']/one-string-test/string");
assertNotNull(pointer);
assertEquals("test", ((Element)pointer.getNode()).getTextContent());
}
public void testNumbers()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/number-test.xsd");
final Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "number-test");
System.err.println("generated xform " + XMLUtil.toString(xformsDocument));
final Element[] repeatedNumbers = Schema2XFormsTest.resolveXFormsControl(xformsDocument, "/number-test/repeated_numbers");
final ChibaBean chibaBean = this.runXForm(xformsDocument);
try
{
chibaBean.dispatch(repeatedNumbers[0].getAttribute("id") + "-insert_before", DOMEventNames.ACTIVATE);
fail("expected to reproduce WCM-778");
}
catch (XFormsException bindingIssue)
{
// tracked as WCM-778
}
}
public void testRepeatConstraintsTest()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/repeat-constraints-test.xsd");
final Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "repeat-constraints-test");
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/one-to-inf",
new SchemaUtil.Occurrence(1, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/zero-to-inf",
new SchemaUtil.Occurrence(0, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/one-to-five",
new SchemaUtil.Occurrence(1, 5));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/three-to-five",
new SchemaUtil.Occurrence(3, 5));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/zero-to-five",
new SchemaUtil.Occurrence(0, 5));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/referenced-string",
new SchemaUtil.Occurrence(1, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-zero-to-inf",
new SchemaUtil.Occurrence(0, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-zero-to-inf/nested-zero-to-inf-inner-zero-to-inf",
new SchemaUtil.Occurrence(0, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-zero-to-inf/nested-zero-to-inf-inner-one-to-inf",
new SchemaUtil.Occurrence(1, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-one-to-inf",
new SchemaUtil.Occurrence(1, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-one-to-inf/nested-one-to-inf-inner-zero-to-inf",
new SchemaUtil.Occurrence(0, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-one-to-inf/nested-one-to-inf-inner-one-to-inf",
new SchemaUtil.Occurrence(1, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-three-to-five",
new SchemaUtil.Occurrence(3, 5));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-three-to-five/nested-three-to-five-inner-zero-to-inf",
new SchemaUtil.Occurrence(0, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-three-to-five/nested-three-to-five-inner-one-to-inf",
new SchemaUtil.Occurrence(1, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-outer-three-to-inf",
new SchemaUtil.Occurrence(3, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-outer-three-to-inf/nested-outer-inner-five-to-inf",
new SchemaUtil.Occurrence(5, SchemaUtil.Occurrence.UNBOUNDED));
Schema2XFormsTest.assertRepeatProperties(xformsDocument,
"/repeat-constraints-test/nested-outer-outer-three-to-inf/nested-outer-inner-five-to-inf/nested-inner-inner-seven-to-inf",
new SchemaUtil.Occurrence(7, SchemaUtil.Occurrence.UNBOUNDED));
this.runXForm(xformsDocument);
}
public void testRootElementWithExtension()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/root-element-with-extension-test.xsd");
Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "without-extension-test");
this.runXForm(xformsDocument);
assertEquals(3, xformsDocument.getElementsByTagNameNS(NamespaceConstants.XFORMS_NS, "input").getLength());
try
{
xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "with-extension-test");
fail("expected failure creating xform with root element with-extension-test in schema " + XMLUtil.toString(schemaDocument));
}
catch (FormBuilderException fbe)
{
LOGGER.debug("got expected exception " + fbe.getMessage());
}
}
public void testSwitch()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/switch-test.xsd");
final Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "switch-test");
this.runXForm(xformsDocument);
// assertEquals(3, xformsDocument.getElementsByTagNameNS(NamespaceConstants.XFORMS_NS, "input").getLength());
//
// try
// {
// xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "with-extension-test");
// fail("expected failure creating xform with root element with-extension-test in schema " + XMLUtil.toString(schemaDocument));
// }
// catch (FormBuilderException fbe)
// {
// }
}
public void testDerivedType()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/derived-type-test.xsd");
final Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "derived-type-test");
this.runXForm(xformsDocument);
LOGGER.debug("generated xforms " + XMLUtil.toString(xformsDocument));
assertBindProperties(xformsDocument,
"/derived-type-test/raw-normalized-string",
"normalizedString",
"normalizedString");
assertControlProperties(xformsDocument,
"/derived-type-test/raw-normalized-string",
NamespaceConstants.XFORMS_PREFIX + ":input");
assertBindProperties(xformsDocument,
"/derived-type-test/non-empty-normalized-string",
"non-empty-normalized-string-type",
"normalizedString");
assertControlProperties(xformsDocument,
"/derived-type-test/non-empty-normalized-string",
NamespaceConstants.XFORMS_PREFIX + ":input");
assertBindProperties(xformsDocument,
"/derived-type-test/raw-string",
"string",
"string");
assertControlProperties(xformsDocument,
"/derived-type-test/raw-string",
NamespaceConstants.XFORMS_PREFIX + ":textarea");
assertBindProperties(xformsDocument,
"/derived-type-test/non-empty-string",
"non-empty-string-type",
"string");
assertControlProperties(xformsDocument,
"/derived-type-test/non-empty-string",
NamespaceConstants.XFORMS_PREFIX + ":textarea");
assertBindProperties(xformsDocument,
"/derived-type-test/raw-any-uri",
"anyURI",
"anyURI");
assertControlProperties(xformsDocument,
"/derived-type-test/raw-any-uri",
NamespaceConstants.XFORMS_PREFIX + ":upload");
assertBindProperties(xformsDocument,
"/derived-type-test/non-empty-any-uri",
"non-empty-any-uri-type",
"anyURI");
assertControlProperties(xformsDocument,
"/derived-type-test/non-empty-any-uri",
NamespaceConstants.XFORMS_PREFIX + ":upload");
assertBindProperties(xformsDocument,
"/derived-type-test/raw-decimal",
"decimal",
"decimal");
assertControlProperties(xformsDocument,
"/derived-type-test/raw-decimal",
NamespaceConstants.XFORMS_PREFIX + ":input");
try
{
assertBindProperties(xformsDocument,
"/derived-type-test/non-zero-decimal",
"non-zero-decimal-type",
"decimal");
fail("expected union type non-zero-decimal to fail");
}
catch (AssertionFailedError ignore)
{
}
assertControlProperties(xformsDocument,
"/derived-type-test/non-zero-decimal",
NamespaceConstants.XFORMS_PREFIX + ":input");
assertBindProperties(xformsDocument,
"/derived-type-test/raw-positive-integer",
"positiveInteger",
"positiveInteger");
Element control = assertControlProperties(xformsDocument,
"/derived-type-test/raw-positive-integer",
NamespaceConstants.XFORMS_PREFIX + ":input");
assertEquals(0, Integer.parseInt(control.getAttributeNS(NamespaceService.ALFRESCO_URI, "fractionDigits")));
assertBindProperties(xformsDocument,
"/derived-type-test/one-to-ten-positive-integer",
"one-to-ten-positive-integer-type",
"positiveInteger");
control = assertControlProperties(xformsDocument,
"/derived-type-test/one-to-ten-positive-integer",
NamespaceConstants.XFORMS_PREFIX + ":range");
assertEquals(1, Integer.parseInt(control.getAttributeNS(NamespaceConstants.XFORMS_NS, "start")));
assertEquals(10, Integer.parseInt(control.getAttributeNS(NamespaceConstants.XFORMS_NS, "end")));
assertEquals(0, Integer.parseInt(control.getAttributeNS(NamespaceService.ALFRESCO_URI, "fractionDigits")));
assertBindProperties(xformsDocument,
"/derived-type-test/raw-boolean",
"boolean",
"boolean");
assertControlProperties(xformsDocument,
"/derived-type-test/raw-boolean",
NamespaceConstants.XFORMS_PREFIX + ":select1");
assertBindProperties(xformsDocument,
"/derived-type-test/always-true-boolean",
"always-true-boolean-type",
"boolean");
assertControlProperties(xformsDocument,
"/derived-type-test/always-true-boolean",
NamespaceConstants.XFORMS_PREFIX + ":select1");
try
{
assertBindProperties(xformsDocument,
"/derived-type-test/raw-any-type",
"anyType",
"anyType");
fail("expected unexpected behavior for anyType");
}
catch (AssertionFailedError ignore)
{
}
assertControlProperties(xformsDocument,
"/derived-type-test/raw-any-type",
NamespaceConstants.XFORMS_PREFIX + ":textarea");
}
public void testRecursive()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/recursive-test.xsd");
Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "non-recursive-test");
this.runXForm(xformsDocument);
try
{
xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "recursive-test");
fail("expected failure creating xform with recursive element definition root element recursive-test in schema " + XMLUtil.toString(schemaDocument));
}
catch (FormBuilderException fbe)
{
LOGGER.debug("got expected exception " + fbe.getMessage());
}
try
{
xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "nested-recursive-test");
fail("expected failure creating xform with recursive element definition root element nested-recursive-test in schema " + XMLUtil.toString(schemaDocument));
}
catch (FormBuilderException fbe)
{
LOGGER.debug("got expected exception " + fbe.getMessage());
}
}
public void testAnnotation()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/annotation-test.xsd");
Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "annotation-test");
this.runXForm(xformsDocument);
System.err.println("generated xform " + XMLUtil.toString(xformsDocument));
Element control = assertControlProperties(xformsDocument,
"/annotation-test/upload_in_root",
NamespaceConstants.XFORMS_PREFIX + ":upload");
assertEquals("upload_in_root", control.getAttributeNS(NamespaceConstants.XFORMS_NS, "appearance"));
control = assertControlProperties(xformsDocument,
"/annotation-test/string_in_root",
NamespaceConstants.XFORMS_PREFIX + ":textarea");
assertEquals("string_in_root", control.getAttributeNS(NamespaceConstants.XFORMS_NS, "appearance"));
control = assertControlProperties(xformsDocument,
"/annotation-test/struct_1/upload_in_base",
NamespaceConstants.XFORMS_PREFIX + ":upload");
assertEquals("upload_in_base", control.getAttributeNS(NamespaceConstants.XFORMS_NS, "appearance"));
control = assertControlProperties(xformsDocument,
"/annotation-test/struct_1/string_in_base",
NamespaceConstants.XFORMS_PREFIX + ":textarea");
assertEquals("string_in_base", control.getAttributeNS(NamespaceConstants.XFORMS_NS, "appearance"));
control = assertControlProperties(xformsDocument,
"/annotation-test/struct_1/upload_in_struct",
NamespaceConstants.XFORMS_PREFIX + ":upload");
assertEquals("upload_in_struct", control.getAttributeNS(NamespaceConstants.XFORMS_NS, "appearance"));
control = assertControlProperties(xformsDocument,
"/annotation-test/struct_1/string_in_struct",
NamespaceConstants.XFORMS_PREFIX + ":textarea");
assertEquals("string_in_struct", control.getAttributeNS(NamespaceConstants.XFORMS_NS, "appearance"));
}
public void testConstraint()
throws Exception
{
final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/constraint-test.xsd");
Document xformsDocument = Schema2XFormsTest.buildXForm(null, schemaDocument, "constraint-test");
final ChibaBean chibaBean = this.runXForm(xformsDocument);
final LinkedList<XMLEvent> events = new LinkedList<XMLEvent>();
final EventListener el = new EventListener()
{
public void handleEvent(final Event e)
{
events.add((XMLEvent)e);
}
};
((EventTarget)chibaBean.getXMLContainer().getDocumentElement()).addEventListener(XFormsEventNames.VALID, el, true);
((EventTarget)chibaBean.getXMLContainer().getDocumentElement()).addEventListener(XFormsEventNames.INVALID, el, true);
((EventTarget)chibaBean.getXMLContainer().getDocumentElement()).addEventListener(XFormsEventNames.SUBMIT_DONE, el, true);
((EventTarget)chibaBean.getXMLContainer().getDocumentElement()).addEventListener(XFormsEventNames.SUBMIT_ERROR, el, true);
Element e = Schema2XFormsTest.resolveXFormsControl(xformsDocument, "/constraint-test/zip-pattern")[0];
chibaBean.updateControlValue(e.getAttribute("id"), "not a zip");
assertEquals(1, events.size());
assertEquals(XFormsEventNames.INVALID, events.get(0).getType());
events.clear();
chibaBean.updateControlValue(e.getAttribute("id"), "94110");
assertEquals(1, events.size());
assertEquals(XFormsEventNames.VALID, events.get(0).getType());
events.clear();
e = Schema2XFormsTest.resolveXFormsControl(xformsDocument, "/constraint-test/email-pattern")[0];
chibaBean.updateControlValue(e.getAttribute("id"), "iamnotanemailaddress");
assertEquals(1, events.size());
assertEquals(XFormsEventNames.INVALID, events.get(0).getType());
events.clear();
chibaBean.updateControlValue(e.getAttribute("id"), "ariel.backenroth@alfresco.org");
assertEquals(1, events.size());
assertEquals(XFormsEventNames.VALID, events.get(0).getType());
events.clear();
Element[] controls = Schema2XFormsTest.resolveXFormsControl(xformsDocument, "/constraint-test/repeated-zip-pattern/.");
assertEquals(3 /* 2 actual + prototype */, controls.length);
Element[] repeat = Schema2XFormsTest.resolveXFormsControl(xformsDocument, "/constraint-test/repeated-zip-pattern");
assertEquals(4 /* 1 repeat + 3 triggers */, repeat.length);
final Element[] bindForRepeat = Schema2XFormsTest.resolveBind(xformsDocument, "/constraint-test/repeated-zip-pattern");
assertEquals(bindForRepeat[bindForRepeat.length - 1].getAttribute("id"), repeat[0].getAttributeNS(NamespaceConstants.XFORMS_NS, "bind"));
for (int i = 1; i <= Integer.parseInt(bindForRepeat[bindForRepeat.length - 1].getAttributeNS(NamespaceConstants.XFORMS_NS, "minOccurs")); i++)
{
chibaBean.updateRepeatIndex(repeat[0].getAttribute("id"), i);
chibaBean.updateControlValue(controls[controls.length - 1].getAttribute("id"), "notavalidzip");
}
// assertEquals("unexpected events " + events, controls.length, events.size());
for (final Event event : events)
{
assertEquals(XFormsEventNames.INVALID, event.getType());
}
events.clear();
chibaBean.dispatch("submit", DOMEventNames.ACTIVATE);
assertEquals(1, events.size());
assertEquals(XFormsEventNames.SUBMIT_ERROR, events.get(0).getType());
events.clear();
for (final Element c : controls)
{
chibaBean.updateControlValue(c.getAttribute("id"), "07666");
}
// assertEquals("unexpected events " + events, controls.length, events.size());
for (final Event event : events)
{
assertEquals(XFormsEventNames.VALID, event.getType());
}
events.clear();
chibaBean.dispatch("submit", DOMEventNames.ACTIVATE);
assertEquals(1, events.size());
assertEquals(XFormsEventNames.SUBMIT_DONE, events.get(0).getType());
}
private static void assertRepeatProperties(final Document xformsDocument,
final String nodeset,
final SchemaUtil.Occurrence o)
{
final Element[] bindElements = Schema2XFormsTest.resolveBind(xformsDocument, nodeset);
assertNotNull("unable to resolve bind for nodeset " + nodeset, bindElements);
assertFalse("unable to resolve bind for nodeset " + nodeset, 0 == bindElements.length);
final Element nodesetBindElement = bindElements[bindElements.length - 1];
assertEquals("unexpected minimum value for nodeset " + nodeset,
o.minimum,
Integer.parseInt(nodesetBindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "minOccurs")));
if (o.isUnbounded())
{
assertEquals("unexpected maximum value for nodeset " + nodeset,
"unbounded",
nodesetBindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs"));
}
else
{
assertEquals("unexpected maximum value for nodeset " + nodeset,
o.maximum,
Integer.parseInt(nodesetBindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs")));
}
assertEquals("unexpected required value for nodeset " + nodeset,
(o.minimum != 0 && nodesetBindElement.hasAttributeNS(NamespaceConstants.XFORMS_NS, "type")) + "()",
nodesetBindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "required"));
JXPathContext xpathContext = JXPathContext.newContext(xformsDocument);
String xpath = "//*[@" + NamespaceConstants.XFORMS_PREFIX + ":bind='" + nodesetBindElement.getAttribute("id") + "']";
assertEquals(4, xpathContext.selectNodes(xpath).size());
xpath = ("//" + NamespaceConstants.XFORMS_PREFIX +
":repeat[@" + NamespaceConstants.XFORMS_PREFIX +
":bind='" + nodesetBindElement.getAttribute("id") + "']");
assertEquals(1, xpathContext.selectNodes(xpath).size());
xpath = ("//" + NamespaceConstants.XFORMS_PREFIX +
":trigger[@" + NamespaceConstants.XFORMS_PREFIX +
":bind='" + nodesetBindElement.getAttribute("id") + "']");
assertEquals(3, xpathContext.selectNodes(xpath).size());
int nestingFactor = 1;
for (int i = 0; i < bindElements.length - 1; i++)
{
final SchemaUtil.Occurrence parentO = Schema2XFormsTest.occuranceFromBind(bindElements[i]);
if (parentO.isRepeated())
{
nestingFactor = nestingFactor * (1 + parentO.minimum);
}
}
final Pointer instance0 = xpathContext.getPointer("//" + NamespaceConstants.XFORMS_PREFIX + ":instance[@id='instance_0']");
assertNotNull(instance0);
assertNotNull(instance0.getNode());
xpathContext = xpathContext.getRelativeContext(instance0);
xpath = nodeset.substring(1);
assertEquals("unexpected result for instance nodeset " + xpath + " in " + instance0.getNode(),
nestingFactor * (o.minimum + 1),
xpathContext.selectNodes(xpath).size());
xpath = nodeset.substring(1) + "[@" + NamespaceService.ALFRESCO_PREFIX + ":prototype='true']";
assertEquals("unexpected result for instance prototype nodeset " + nodeset + " in " + instance0.getNode(),
nestingFactor,
xpathContext.selectNodes(xpath).size());
}
private static Element assertBindProperties(final Document xformsDocument,
final String nodeset,
final String schemaType,
final String builtInType)
{
final Element[] binds = Schema2XFormsTest.resolveBind(xformsDocument, nodeset);
assertEquals("unexpected type for nodeset " + nodeset,
schemaType,
binds[binds.length - 1].getAttributeNS(NamespaceConstants.XFORMS_NS, "type"));
assertEquals("unexpected built in type for nodeset " + nodeset,
builtInType,
binds[binds.length - 1].getAttributeNS(NamespaceService.ALFRESCO_URI, "builtInType"));
return binds[binds.length - 1];
}
private static Element assertControlProperties(final Document xformsDocument,
final String nodeset,
final String controlType)
{
final Element[] controls = Schema2XFormsTest.resolveXFormsControl(xformsDocument, nodeset);
assertEquals("unexpected xforms control for " + nodeset,
controlType,
controls[controls.length - 1].getNodeName());
return controls[controls.length - 1];
}
/**
* Returns the resolved bind and all parents binds for the nodeset.
*/
private static Element[] resolveBind(final Document xformsDocument, final String nodeset)
{
JXPathContext xpathContext = JXPathContext.newContext(xformsDocument);
assertNotNull(nodeset);
assertEquals('/', nodeset.charAt(0));
final String rootNodePath = nodeset.replaceFirst("(\\/[^\\/]+).*", "$1");
assertNotNull(rootNodePath);
String xpath = ("//" + NamespaceConstants.XFORMS_PREFIX +
":bind[@" + NamespaceConstants.XFORMS_PREFIX +
":nodeset='" + rootNodePath + "']");
Pointer pointer = xpathContext.getPointer(xpath);
assertNotNull("unable to resolve xpath for root node " + xpath, pointer);
assertNotNull("unable to resolve xpath for root node " + xpath, pointer.getNode());
if (nodeset.equals(rootNodePath))
{
return new Element[] { (Element)pointer.getNode() };
}
xpathContext = xpathContext.getRelativeContext(pointer);
// substring the path to the next slash and split it
final LinkedList<Element> result = new LinkedList<Element>();
result.add((Element)pointer.getNode());
for (String p : nodeset.substring(rootNodePath.length() + 1).split("/"))
{
xpath = NamespaceConstants.XFORMS_PREFIX + ":bind[starts-with(@" + NamespaceConstants.XFORMS_PREFIX + ":nodeset, '" + p + "')]";
pointer = xpathContext.getPointer(xpath);
assertNotNull("unable to resolve path " + xpath +
" on bind with nodeset " + result.getLast().getAttributeNS(NamespaceConstants.XFORMS_NS, "nodeset"),
pointer);
assertNotNull("unable to resolve path " + xpath +
" on bind with nodeset " + result.getLast().getAttributeNS(NamespaceConstants.XFORMS_NS, "nodeset"),
pointer.getNode());
xpathContext = xpathContext.getRelativeContext(pointer);
result.add((Element)pointer.getNode());
}
return (Element[])result.toArray(new Element[result.size()]);
}
private static Element[] resolveXFormsControl(final Document xformsDocument,
final String nodeset)
{
final Element[] binds = Schema2XFormsTest.resolveBind(xformsDocument, nodeset);
assertNotNull(binds);
assertFalse(binds.length == 0);
final String bindId = binds[binds.length - 1].getAttribute("id");
final JXPathContext xpathContext = JXPathContext.newContext(xformsDocument);
String xpath = "//*[@" + NamespaceConstants.XFORMS_PREFIX + ":bind='" + bindId + "']";
return (Element[])xpathContext.selectNodes(xpath).toArray(new Element[0]);
}
private Document loadTestResourceDocument(final String path)
throws IOException, SAXException
{
File f = new File(this.getResourcesDir());
for (final String p : path.split("/"))
{
f = new File(f, p);
}
return XMLUtil.parse(f);
}
private ChibaBean runXForm(final Document xformsDocument)
throws Exception
{
final ChibaBean chibaBean = new ChibaBean();
String webResourceDir = System.getProperty("alfresco.web.resources.dir",
this.getResourcesDir() + File.separator + ".." + File.separator + "web");
chibaBean.setConfig(webResourceDir + File.separator +
"WEB-INF" + File.separator + "chiba.xml");
chibaBean.setXMLContainer(xformsDocument);
chibaBean.init();
return chibaBean;
}
private static Document buildXForm(final Document instanceDocument,
final Document schemaDocument,
final String rootElementName)
throws FormBuilderException
{
final Schema2XForms s2xf = new Schema2XForms("/test_action",
Schema2XForms.SubmitMethod.POST,
"echo://fake.base.url", true);
return s2xf.buildXForm(instanceDocument,
schemaDocument,
rootElementName,
new ResourceBundle()
{
public Object handleGetObject(final String key)
{
if (key == null)
{
throw new NullPointerException();
}
return null;
}
public Enumeration<String> getKeys()
{
return new Vector<String>().elements();
}
}).getFirst();
}
private static SchemaUtil.Occurrence occuranceFromBind(final Element bindElement)
{
return new SchemaUtil.Occurrence(bindElement.hasAttributeNS(NamespaceConstants.XFORMS_NS, "minOccurs")
? Integer.parseInt(bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "minOccurs"))
: 1,
bindElement.hasAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs")
? ("unbounded".equals(bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs"))
? SchemaUtil.Occurrence.UNBOUNDED
: Integer.parseInt(bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs")))
: 1);
}
}
@@ -426,8 +426,12 @@ public class XFormsProcessor implements FormProcessor
{
return result;
}
throw new RuntimeException("widget definitions " + this +
" and " + other + " collide");
if (LOGGER.isInfoEnabled())
{
LOGGER.info("widget definitions " + this + " and " + other + " may collide");
}
return 0;
}
public String toString()
@@ -0,0 +1,100 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.ui.common;
import java.util.List;
import org.alfresco.web.bean.repository.Node;
/**
* Helper class to get next or previos node from the list of nodes.
*
* @author vdanilchenko
* @since 4.1.3
*/
public class NodeListUtils
{
/**
* @param nodes the list of the nodes
* @param currentNodeId the current node ID
*/
public static Node nextItem(List<? extends Node> nodes, String currentNodeId)
{
Node next = null;
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i=0; i<nodes.size(); i++)
{
if (currentNodeId.equals(nodes.get(i).getId()) == true)
{
// found our item - navigate to next
if (i != nodes.size() - 1)
{
next = nodes.get(i + 1);
}
else
{
// handle wrapping case
next = nodes.get(0);
}
break;
}
}
return next;
}
/**
* @param nodes the list of the nodes
* @param currentNodeId the current node ID
*/
public static Node previousItem(List<? extends Node> nodes, String currentNodeId)
{
Node previous = null;
// perform a linear search - this is slow but stateless
// otherwise we would have to manage state of last selected node
// this gets very tricky as this bean is instantiated once and never
// reset - it does not know when the document has changed etc.
for (int i=0; i<nodes.size(); i++)
{
if (currentNodeId.equals(nodes.get(i).getId()) == true)
{
// found our item - navigate to previous
if (i != 0)
{
previous = nodes.get(i - 1);
}
else
{
// handle wrapping case
previous = nodes.get(nodes.size() - 1);
}
break;
}
}
return previous;
}
}
@@ -0,0 +1,118 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.ui.common;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.web.bean.repository.DataDictionary;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.app.Application;
import org.springframework.web.jsf.FacesContextUtils;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import javax.faces.context.FacesContext;
/**
* Comparator to sort the list of nodes according theirs properties and sort order
*
* @author vdanilchenko
* @since 4.1.3
*/
public class NodePropertyComparator implements Comparator<Object>
{
private String propertyName;
private boolean isAscending;
private DataDictionary dataDictionary;
/**
* @param propertyName the property name to sort
* @param isAscending sort order
*/
public NodePropertyComparator(String propertyName, boolean isAscending)
{
super();
this.propertyName = propertyName;
this.isAscending = isAscending;
FacesContext context = FacesContext.getCurrentInstance();
dataDictionary = (DataDictionary)FacesContextUtils.getRequiredWebApplicationContext(context).getBean(Application.BEAN_DATA_DICTIONARY);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public int compare(Object node1, Object node2)
{
Map<String, Object> nodeProperties1 = ((Node)node1).getProperties();
Map<String, Object> nodeProperties2 = ((Node)node2).getProperties();
PropertyDefinition pd1 = dataDictionary.getPropertyDefinition((Node)node1, propertyName);
PropertyDefinition pd2 = dataDictionary.getPropertyDefinition((Node)node2, propertyName);
Comparable propertyValue1, propertyValue2;
if((pd1 != null) && (pd2 != null))
{
String typeName = pd1.getDataType().getName().getLocalName();
if(typeName.equals("datetime"))
{
propertyValue1 = (Date) nodeProperties1.get(propertyName);
propertyValue2 = (Date) nodeProperties2.get(propertyName);
}
else if(typeName.equals("long"))
{
propertyValue1 = (Long) nodeProperties1.get(propertyName);
propertyValue2 = (Long) nodeProperties2.get(propertyName);
}
else if(typeName.equals("boolean"))
{
propertyValue1 = (Boolean) nodeProperties1.get(propertyName);
propertyValue2 = (Boolean) nodeProperties2.get(propertyName);
}
//string types: text, mltext
//non comparable types: locale, content
else
{
propertyValue1 = nodeProperties1.get(propertyName).toString();
propertyValue2 = nodeProperties2.get(propertyName).toString();
}
}
//additional properties doesn't contains in the node properties
//their type can't be resolved using DataDictionary
//QNameNodeMap resolves them on first invocation and puts them into the map of node properties
else
{
if(propertyName.equals("size"))
{
propertyValue1 = (Long) nodeProperties1.get(propertyName);
propertyValue2 = (Long) nodeProperties2.get(propertyName);
}
else
{
propertyValue1 = nodeProperties1.get(propertyName).toString();
propertyValue2 = nodeProperties2.get(propertyName).toString();
}
}
if(isAscending)
{
return propertyValue1.compareTo(propertyValue2);
}
return propertyValue2.compareTo(propertyValue1);
}
}
@@ -1,392 +1,380 @@
/*
* Copyright (C) 2005-2013 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* There is an Enterprise overlay for this file
*/
package org.alfresco.web.ui.repo.tag;
import java.io.IOException;
import java.io.Writer;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.coci.CCProperties;
import org.alfresco.web.config.ClientConfigElement;
import org.alfresco.web.ui.common.Utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A non-JSF tag library that adds the HTML begin and end tags if running in servlet mode
*
* @author gavinc
*/
public class PageTag extends TagSupport
{
private static final long serialVersionUID = 8142765393181557228L;
private final static String SCRIPTS_START = "<script type=\"text/javascript\" src=\"";
private final static String SCRIPTS_END = "\"></script>\n";
private final static String STYLES_START = "<link rel=\"stylesheet\" href=\"";
private final static String STYLES_MAIN = "\" type=\"text/css\">\n";
private final static String[] SCRIPTS =
{
// menu javascript
"/scripts/menu.js",
// webdav javascript
"/scripts/webdav.js",
// base yahoo file
"/scripts/ajax/yahoo/yahoo/yahoo-min.js",
// io handling (AJAX)
"/scripts/ajax/yahoo/connection/connection-min.js",
// event handling
"/scripts/ajax/yahoo/event/event-min.js",
// mootools
"/scripts/ajax/mootools.v1.11.js",
// common Alfresco util methods
"/scripts/ajax/common.js",
// pop-up panel helper objects
"/scripts/ajax/summary-info.js",
// ajax pickers
"/scripts/ajax/picker.js",
"/scripts/ajax/tagger.js",
// validation handling
"/scripts/validation.js"
};
private final static String[] CSS =
{
"/css/main.css",
"/css/picker.css"
};
/**
* Please ensure you understand the terms of the license before changing the contents of this file.
*/
private final static String ALF_LOGO_HTTP = "http://www.alfresco.com/assets/images/logos/community-4.2.png";
private final static String ALF_LOGO_HTTPS = "https://www.alfresco.com/assets/images/logos/community-4.2.png";
private final static String ALF_URL = "http://www.alfresco.com";
private final static String ALF_TEXT = "Alfresco Community";
private final static String ALF_COPY = "Supplied free of charge with " +
"<a class='footer' href='http://www.alfresco.com/services/support/communityterms/#support'>no support</a>, " +
"<a class='footer' href='http://www.alfresco.com/services/support/communityterms/#certification'>no certification</a>, " +
"<a class='footer' href='http://www.alfresco.com/services/support/communityterms/#maintenance'>no maintenance</a>, " +
"<a class='footer' href='http://www.alfresco.com/services/support/communityterms/#warranty'>no warranty</a> and " +
"<a class='footer' href='http://www.alfresco.com/services/support/communityterms/#indemnity'>no indemnity</a> by " +
"<a class='footer' href='http://www.alfresco.com'>Alfresco</a> or its " +
"<a class='footer' href='http://www.alfresco.com/partners/'>Certified Partners</a>. " +
"<a class='footer' href='http://www.alfresco.com/services/support/'>Click here for support</a>. " +
"Alfresco Software Inc. &copy; 2005-2013 All rights reserved.";
private final static Log logger = LogFactory.getLog(PageTag.class);
private static String alfresco = null;
private static String loginPage = null;
private long startTime = 0;
private String title;
private String titleId;
private String doctypeRootElement;
private String doctypePublic;
private String doctypeSystem;
/**
* @return The title for the page
*/
public String getTitle()
{
return title;
}
/**
* @param title Sets the page title
*/
public void setTitle(String title)
{
this.title = title;
}
/**
* @return The title message Id for the page
*/
public String getTitleId()
{
return titleId;
}
/**
* @param titleId Sets the page title message Id
*/
public void setTitleId(String titleId)
{
this.titleId = titleId;
}
public String getDoctypeRootElement()
{
return this.doctypeRootElement;
}
public void setDoctypeRootElement(final String doctypeRootElement)
{
this.doctypeRootElement = doctypeRootElement;
}
public String getDoctypePublic()
{
return this.doctypePublic;
}
public void setDoctypePublic(final String doctypePublic)
{
this.doctypePublic = doctypePublic;
}
public String getDoctypeSystem()
{
return this.doctypeSystem;
}
public void setDoctypeSystem(final String doctypeSystem)
{
this.doctypeSystem = doctypeSystem;
}
public void release()
{
super.release();
this.title = null;
this.titleId = null;
this.doctypeRootElement = null;
this.doctypeSystem = null;
this.doctypePublic = null;
}
/**
* @see javax.servlet.jsp.tagext.TagSupport#doStartTag()
*/
public int doStartTag() throws JspException
{
if (logger.isDebugEnabled())
startTime = System.currentTimeMillis();
try
{
String reqPath = ((HttpServletRequest)pageContext.getRequest()).getContextPath();
Writer out = pageContext.getOut();
if (!Application.inPortalServer())
{
if (this.getDoctypeRootElement() != null &&
this.getDoctypePublic() != null)
{
out.write("<!DOCTYPE ");
out.write(this.getDoctypeRootElement().toLowerCase());
out.write(" PUBLIC \"" + this.getDoctypePublic() + "\"");
if (this.getDoctypeSystem() != null)
{
out.write(" \"" + this.getDoctypeSystem() + "\"");
}
out.write(">\n");
}
else
{
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n");
out.write(" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
}
out.write("<html><head>");
out.write("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\" />\n");
out.write("<title>");
if (this.titleId != null && this.titleId.length() != 0)
{
out.write(Utils.encode(Application.getMessage(pageContext.getSession(), this.titleId)));
}
else if (this.title != null && this.title.length() != 0)
{
out.write(Utils.encode(this.title));
}
else
{
out.write("Alfresco Web Client");
}
out.write("</title>\n");
out.write("<link rel=\"search\" type=\"application/opensearchdescription+xml\" href=\"" + reqPath +
"/wcservice/api/search/keyword/description.xml\" title=\"Alfresco Keyword Search\">\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n");
}
// CSS style includes
for (final String css : PageTag.CSS)
{
out.write(STYLES_START);
out.write(reqPath);
out.write(css);
out.write(STYLES_MAIN);
}
// JavaScript includes
for (final String s : PageTag.SCRIPTS)
{
out.write(SCRIPTS_START);
out.write(reqPath);
out.write(s);
out.write(SCRIPTS_END);
}
out.write("<script type=\"text/javascript\">"); // start - generate naked javascript code
// get client config to determine how the JavaScript setContextPath should behave
ClientConfigElement clientConfig = Application.getClientConfig(pageContext.getServletContext());
// set the context path used by some Alfresco script objects
if (clientConfig != null && clientConfig.getCheckContextAgainstPath())
{
out.write("setCheckContextAgainstPath(true);");
}
out.write("setContextPath('");
out.write(reqPath);
out.write("');");
// generate window onload code
generateWindowOnloadCode(out);
out.write("</script>\n"); // end - generate naked javascript code
if (!Application.inPortalServer())
{
out.write("</head>");
out.write("<body>\n");
}
}
catch (IOException ioe)
{
throw new JspException(ioe.toString());
}
return EVAL_BODY_INCLUDE;
}
/**
* @see javax.servlet.jsp.tagext.TagSupport#doEndTag()
*/
public int doEndTag() throws JspException
{
try
{
HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
if (req.getRequestURI().endsWith(getLoginPage()) == false)
{
pageContext.getOut().write(getAlfrescoButton());
}
if (!Application.inPortalServer())
{
pageContext.getOut().write("\n</body></html>");
}
}
catch (IOException ioe)
{
throw new JspException(ioe.toString());
}
if (logger.isDebugEnabled())
{
long endTime = System.currentTimeMillis();
logger.debug("Time to generate page: " + (endTime - startTime) + "ms");
}
return super.doEndTag();
}
private String getLoginPage()
{
if (PageTag.loginPage == null)
{
PageTag.loginPage = Application.getLoginPage(pageContext.getServletContext());
}
return PageTag.loginPage;
}
/**
* Please ensure you understand the terms of the license before changing the contents of this file.
*/
private String getAlfrescoButton()
{
if (PageTag.alfresco == null)
{
final HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
PageTag.alfresco = ("<center><table style='margin: 0px auto;'><tr><td>" +
"<a href='" + ALF_URL + "'>" +
"<img style='vertical-align:middle;border-width:0px;' width='176' height='26' alt='' title='" + ALF_TEXT +
"' src='" + ("http".equals(req.getScheme()) ? ALF_LOGO_HTTP : ALF_LOGO_HTTPS) +
"'>" +"</a></td><td align='center'>" +
"<span class='footer'>" + ALF_COPY +
"</span></td><td></td></tr></table></center>");
}
return PageTag.alfresco;
}
/**
* This method generate code for setting window.onload reference as
* we need to open WebDav or CIFS URL in a new window.
*
* Executes via javascript code(function onloadFunc()) in "onload.js" include file.
*
* @return Returns window.onload javascript code
*/
private static void generateWindowOnloadCode(Writer out)
throws IOException
{
FacesContext fc = FacesContext.getCurrentInstance();
if (fc != null)
{
CCProperties ccProps = (CCProperties)FacesHelper.getManagedBean(fc, "CCProperties");
if (ccProps.getWebdavUrl() != null || ccProps.getCifsPath() != null)
{
out.write("window.onload=function(){onloadFunc(\"");
if (ccProps.getWebdavUrl() != null)
{
out.write(ccProps.getWebdavUrl());
}
out.write("\",\"");
if (ccProps.getCifsPath() != null)
{
String val = ccProps.getCifsPath();
val = Utils.replace(val, "\\", "\\\\"); // encode escape character
out.write(val);
}
out.write("\");};");
// reset session bean state
ccProps.setCifsPath(null);
ccProps.setWebdavUrl(null);
}
}
}
}
/*
* Copyright (C) 2005-2013 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
/* Enterprise overlay */
package org.alfresco.web.ui.repo.tag;
import java.io.IOException;
import java.io.Writer;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.coci.CCProperties;
import org.alfresco.web.config.ClientConfigElement;
import org.alfresco.web.ui.common.Utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A non-JSF tag library that adds the HTML begin and end tags if running in servlet mode
*
* @author gavinc
*/
public class PageTag extends TagSupport
{
private static final long serialVersionUID = 8142765393181557228L;
private final static String SCRIPTS_START = "<script type=\"text/javascript\" src=\"";
private final static String SCRIPTS_END = "\"></script>\n";
private final static String STYLES_START = "<link rel=\"stylesheet\" href=\"";
private final static String STYLES_MAIN = "\" type=\"text/css\">\n";
private final static String[] SCRIPTS =
{
// menu javascript
"/scripts/menu.js",
// webdav javascript
"/scripts/webdav.js",
// base yahoo file
"/scripts/ajax/yahoo/yahoo/yahoo-min.js",
// io handling (AJAX)
"/scripts/ajax/yahoo/connection/connection-min.js",
// event handling
"/scripts/ajax/yahoo/event/event-min.js",
// mootools
"/scripts/ajax/mootools.v1.11.js",
// common Alfresco util methods
"/scripts/ajax/common.js",
// pop-up panel helper objects
"/scripts/ajax/summary-info.js",
// ajax pickers
"/scripts/ajax/picker.js",
"/scripts/ajax/tagger.js",
// validation handling
"/scripts/validation.js"
};
private final static String[] CSS =
{
"/css/main.css",
"/css/picker.css"
};
/**
* Please ensure you understand the terms of the license before changing the contents of this file.
*/
private final static String ALF_URL = "http://www.alfresco.com";
private final static String ALF_LOGO = "/images/logo/alfresco_enterprise.gif";
private final static String ALF_TEXT = "Alfresco Enterprise";
private final static String ALF_COPY = "Certified and supported. Alfresco Software Inc. &copy; 2005-2013 All rights reserved.";
private final static Log logger = LogFactory.getLog(PageTag.class);
private static String alfresco = null;
private static String loginPage = null;
private long startTime = 0;
private String title;
private String titleId;
private String doctypeRootElement;
private String doctypePublic;
private String doctypeSystem;
/**
* @return The title for the page
*/
public String getTitle()
{
return title;
}
/**
* @param title Sets the page title
*/
public void setTitle(String title)
{
this.title = title;
}
/**
* @return The title message Id for the page
*/
public String getTitleId()
{
return titleId;
}
/**
* @param titleId Sets the page title message Id
*/
public void setTitleId(String titleId)
{
this.titleId = titleId;
}
public String getDoctypeRootElement()
{
return this.doctypeRootElement;
}
public void setDoctypeRootElement(final String doctypeRootElement)
{
this.doctypeRootElement = doctypeRootElement;
}
public String getDoctypePublic()
{
return this.doctypePublic;
}
public void setDoctypePublic(final String doctypePublic)
{
this.doctypePublic = doctypePublic;
}
public String getDoctypeSystem()
{
return this.doctypeSystem;
}
public void setDoctypeSystem(final String doctypeSystem)
{
this.doctypeSystem = doctypeSystem;
}
public void release()
{
super.release();
this.title = null;
this.titleId = null;
this.doctypeRootElement = null;
this.doctypeSystem = null;
this.doctypePublic = null;
}
/**
* @see javax.servlet.jsp.tagext.TagSupport#doStartTag()
*/
public int doStartTag() throws JspException
{
if (logger.isDebugEnabled())
startTime = System.currentTimeMillis();
try
{
String reqPath = ((HttpServletRequest)pageContext.getRequest()).getContextPath();
Writer out = pageContext.getOut();
if (!Application.inPortalServer())
{
if (this.getDoctypeRootElement() != null &&
this.getDoctypePublic() != null)
{
out.write("<!DOCTYPE ");
out.write(this.getDoctypeRootElement().toLowerCase());
out.write(" PUBLIC \"" + this.getDoctypePublic() + "\"");
if (this.getDoctypeSystem() != null)
{
out.write(" \"" + this.getDoctypeSystem() + "\"");
}
out.write(">\n");
}
else
{
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n");
out.write(" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
}
out.write("<html><head>");
out.write("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\" />\n");
out.write("<title>");
if (this.titleId != null && this.titleId.length() != 0)
{
out.write(Utils.encode(Application.getMessage(pageContext.getSession(), this.titleId)));
}
else if (this.title != null && this.title.length() != 0)
{
out.write(Utils.encode(this.title));
}
else
{
out.write("Alfresco Web Client");
}
out.write("</title>\n");
out.write("<link rel=\"search\" type=\"application/opensearchdescription+xml\" href=\"" + reqPath +
"/wcservice/api/search/keyword/description.xml\" title=\"Alfresco Keyword Search\">\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n");
}
// CSS style includes
for (final String css : PageTag.CSS)
{
out.write(STYLES_START);
out.write(reqPath);
out.write(css);
out.write(STYLES_MAIN);
}
// JavaScript includes
for (final String s : PageTag.SCRIPTS)
{
out.write(SCRIPTS_START);
out.write(reqPath);
out.write(s);
out.write(SCRIPTS_END);
}
out.write("<script type=\"text/javascript\">"); // start - generate naked javascript code
// get client config to determine how the JavaScript setContextPath should behave
ClientConfigElement clientConfig = Application.getClientConfig(pageContext.getServletContext());
// set the context path used by some Alfresco script objects
if (clientConfig != null && clientConfig.getCheckContextAgainstPath())
{
out.write("setCheckContextAgainstPath(true);");
}
out.write("setContextPath('");
out.write(reqPath);
out.write("');");
// generate window onload code
generateWindowOnloadCode(out);
out.write("</script>\n"); // end - generate naked javascript code
if (!Application.inPortalServer())
{
out.write("</head>");
out.write("<body>\n");
}
}
catch (IOException ioe)
{
throw new JspException(ioe.toString());
}
return EVAL_BODY_INCLUDE;
}
/**
* @see javax.servlet.jsp.tagext.TagSupport#doEndTag()
*/
public int doEndTag() throws JspException
{
try
{
HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
if (req.getRequestURI().endsWith(getLoginPage()) == false)
{
pageContext.getOut().write(getAlfrescoButton());
}
if (!Application.inPortalServer())
{
pageContext.getOut().write("\n</body></html>");
}
}
catch (IOException ioe)
{
throw new JspException(ioe.toString());
}
if (logger.isDebugEnabled())
{
long endTime = System.currentTimeMillis();
logger.debug("Time to generate page: " + (endTime - startTime) + "ms");
}
return super.doEndTag();
}
private String getLoginPage()
{
if (PageTag.loginPage == null)
{
PageTag.loginPage = Application.getLoginPage(pageContext.getServletContext());
}
return PageTag.loginPage;
}
/**
* Please ensure you understand the terms of the license before changing the contents of this file.
*/
private String getAlfrescoButton()
{
if (PageTag.alfresco == null)
{
final String reqPath = ((HttpServletRequest)pageContext.getRequest()).getContextPath();
PageTag.alfresco = ("<center><table style='margin: 0px auto;'><tr><td>" +
"<a href='" + ALF_URL + "'>" +
"<img style='vertical-align:middle;border-width:0px;' width='164' height='26' alt='' title='" + ALF_TEXT +
"' src='" + reqPath + ALF_LOGO + "'/>" +
"</a></td><td align='center'>" +
"<span class='footer'>" + ALF_COPY +
"</span></td><td></td></tr></table></center>");
}
return PageTag.alfresco;
}
/**
* This method generate code for setting window.onload reference as
* we need to open WebDav or CIFS URL in a new window.
*
* Executes via javascript code(function onloadFunc()) in "onload.js" include file.
*
* @return Returns window.onload javascript code
*/
private static void generateWindowOnloadCode(Writer out)
throws IOException
{
FacesContext fc = FacesContext.getCurrentInstance();
if (fc != null)
{
CCProperties ccProps = (CCProperties)FacesHelper.getManagedBean(fc, "CCProperties");
if (ccProps.getWebdavUrl() != null || ccProps.getCifsPath() != null)
{
out.write("window.onload=function(){onloadFunc(\"");
if (ccProps.getWebdavUrl() != null)
{
out.write(ccProps.getWebdavUrl());
}
out.write("\",\"");
if (ccProps.getCifsPath() != null)
{
String val = ccProps.getCifsPath();
val = Utils.replace(val, "\\", "\\\\"); // encode escape character
out.write(val);
}
out.write("\");};");
// reset session bean state
ccProps.setCifsPath(null);
ccProps.setWebdavUrl(null);
}
}
}
}