mirror of
https://github.com/Alfresco/acs-community-packaging.git
synced 2026-09-16 18:13:21 +00:00
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:
@@ -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. © 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. © 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user