Merged V2.2 to HEAD (V2.1 sourced fixes)

7121: Merged V2.1 to V2.2
      7049: Fix for unreported duplicate component ID error (very rarely seen) in browse WCM sandbox JSP
      7058: Fixes failure to rollback correctly on failed alfresco->alfresco deployment.
      7074: Added filtering/access control checks to the AVM virtualization view.
      7083: Added transaction handling to calls involving preview store
      7084: xmlsec library update to 1.4.1
      7092: Missing config update from the AVM filtering checkin.
   7124: Merged V2.1 to V2.2
      7091: Fix to several issues found with Regenerate Renditions wizard and FormsService
   7125: Merged V2.1 to V2.2
      7093: Fixes to workaround some deployment issues being experienced by a customer.
      7094: Fix for previous build failure


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@7373 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-11-13 02:41:28 +00:00
parent 59458fb578
commit dd06e3166b
20 changed files with 1317 additions and 226 deletions

View File

@@ -182,3 +182,6 @@ patch.emailContributorGroup.description=Adds the 'GROUP_EMAIL_CONTRIBUTORS' grou
patch.avmStoreAsIdentifier.description=Reindex wca:webfolder to make wca:avmstore an identifier patch.avmStoreAsIdentifier.description=Reindex wca:webfolder to make wca:avmstore an identifier
patch.avmStoreAsIdentifier.result=Reindexed wca:webfolder to make wca:avmstore an identifier patch.avmStoreAsIdentifier.result=Reindexed wca:webfolder to make wca:avmstore an identifier
patch.avmFormPropertyIdentifier.description=Reindex wca:webform to make wca:formname an identifier
patch.avmFormPropertyIdentifier.result=Reindexed wca:webform to make wca:formname an identifier

View File

@@ -110,11 +110,11 @@
<properties> <properties>
<property name="wca:username"> <property name="wca:username">
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:role"> <property name="wca:role">
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
</properties> </properties>
</type> </type>
@@ -125,7 +125,12 @@
<properties> <properties>
<property name="wca:formname"> <property name="wca:formname">
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
<index enabled="true">
<atomic>true</atomic>
<stored>false</stored>
<tokenised>false</tokenised>
</index>
</property> </property>
</properties> </properties>
<associations> <associations>
@@ -164,7 +169,7 @@
<properties> <properties>
<property name="wca:baserenderingenginetemplatename"> <property name="wca:baserenderingenginetemplatename">
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
</properties> </properties>
<mandatory-aspects> <mandatory-aspects>
@@ -178,7 +183,7 @@
<properties> <properties>
<property name="wca:workflowname"> <property name="wca:workflowname">
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:workflowdefaultproperties"> <property name="wca:workflowdefaultproperties">
<type>d:content</type> <type>d:content</type>
@@ -203,7 +208,7 @@
<property name="wca:mimetypeforrendition"> <property name="wca:mimetypeforrendition">
<title>Mimetype for generated assets</title> <title>Mimetype for generated assets</title>
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
</properties> </properties>
<mandatory-aspects> <mandatory-aspects>
@@ -223,22 +228,22 @@
<property name="wca:deployserver"> <property name="wca:deployserver">
<title>Server Deployed To</title> <title>Server Deployed To</title>
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:deployversion"> <property name="wca:deployversion">
<title>Snapshot Version Deployed</title> <title>Snapshot Version Deployed</title>
<type>d:int</type> <type>d:int</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:deploystarttime"> <property name="wca:deploystarttime">
<title>Time Deploy Started</title> <title>Time Deploy Started</title>
<type>d:datetime</type> <type>d:datetime</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:deployendtime"> <property name="wca:deployendtime">
<title>Time Deploy Finished</title> <title>Time Deploy Finished</title>
<type>d:datetime</type> <type>d:datetime</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:deploysuccessful"> <property name="wca:deploysuccessful">
<title>Deployment Successful</title> <title>Deployment Successful</title>
@@ -284,12 +289,12 @@
<property name="wca:xmlschemarootelementname"> <property name="wca:xmlschemarootelementname">
<title>Schema Root Element Name</title> <title>Schema Root Element Name</title>
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:xmlschema"> <property name="wca:xmlschema">
<title>Schema</title> <title>Schema</title>
<type>d:noderef</type> <type>d:noderef</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
</properties> </properties>
<associations> <associations>
@@ -325,15 +330,15 @@
<aspect name="wca:renderingenginetemplate"> <aspect name="wca:renderingenginetemplate">
<title>A Rendering Engine</title> <title>A Rendering Engine</title>
<properties> <properties>
<property name="wca:parentrendereringenginename"> <property name="wca:parentrenderingenginename">
<title>Type</title> <title>Type</title>
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:formsource"> <property name="wca:formsource">
<title>Form Source</title> <title>Form Source</title>
<type>d:noderef</type> <type>d:noderef</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
</properties> </properties>
<associations> <associations>
@@ -359,7 +364,7 @@
<property name="wca:parentformname"> <property name="wca:parentformname">
<title>Form that generated this asset</title> <title>Form that generated this asset</title>
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:originalparentpath"> <property name="wca:originalparentpath">
<title>The original parent path when this form instance data was created - used for regenerating accurately.</title> <title>The original parent path when this form instance data was created - used for regenerating accurately.</title>
@@ -381,17 +386,17 @@
<property name="wca:parentrenderingenginetemplate"> <property name="wca:parentrenderingenginetemplate">
<title>Form data renderer that generated this asset</title> <title>Form data renderer that generated this asset</title>
<type>d:noderef</type> <type>d:noderef</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:parentrenditionproperties"> <property name="wca:parentrenditionproperties">
<title>Rendition properties used for this rendition</title> <title>Rendition properties used for this rendition</title>
<type>d:noderef</type> <type>d:noderef</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
<property name="wca:primaryforminstancedata"> <property name="wca:primaryforminstancedata">
<title>Primary XML Asset used to generate this asset</title> <title>Primary XML Asset used to generate this asset</title>
<type>d:text</type> <type>d:text</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
</properties> </properties>
</aspect> </aspect>
@@ -402,7 +407,7 @@
<property name="wca:expirationDate"> <property name="wca:expirationDate">
<title>Expiration Date</title> <title>Expiration Date</title>
<type>d:datetime</type> <type>d:datetime</type>
<mandatory>true</mandatory> <mandatory enforced="true">true</mandatory>
</property> </property>
</properties> </properties>
</aspect> </aspect>

View File

@@ -94,6 +94,7 @@
<property name="mimetypeService"><ref bean="mimetypeService" /></property> <property name="mimetypeService"><ref bean="mimetypeService" /></property>
<property name="serviceRegistry"><ref bean="ServiceRegistry"/></property> <property name="serviceRegistry"><ref bean="ServiceRegistry"/></property>
<property name="stateReaper"><ref bean="fileStateReaper"/></property> <property name="stateReaper"><ref bean="fileStateReaper"/></property>
<property name="nodeService"><ref bean="NodeService" /></property>
<property name="createStoreListener"><ref bean="createStoreTxnListener"/></property> <property name="createStoreListener"><ref bean="createStoreTxnListener"/></property>
<property name="purgeStoreListener"><ref bean="purgeStoreTxnListener"/></property> <property name="purgeStoreListener"><ref bean="purgeStoreTxnListener"/></property>

View File

@@ -1109,5 +1109,19 @@
</list> </list>
</property> </property>
</bean> </bean>
<bean id="patch.avmFormPropertyIdentifier" class="org.alfresco.repo.admin.patch.impl.AVMFormsPropertyTokenisationPatch" parent="basePatch" >
<property name="id"><value>patch.avmFormPropertyIdentifier</value></property>
<property name="description"><value>patch.avmFormPropertyIdentifier.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>111</value></property>
<property name="targetSchema"><value>112</value></property>
<property name="spacesImporterBootstrap">
<ref bean="spacesBootstrap" />
</property>
<property name="indexerAndSearcher">
<ref bean="indexerAndSearcherFactory" />
</property>
</bean>
</beans> </beans>

View File

@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number # Schema number
version.schema=111 version.schema=112

View File

@@ -38,7 +38,7 @@ import org.alfresco.repo.avm.CreateVersionCallback;
import org.alfresco.repo.avm.PurgeStoreCallback; import org.alfresco.repo.avm.PurgeStoreCallback;
import org.alfresco.repo.avm.PurgeVersionCallback; import org.alfresco.repo.avm.PurgeVersionCallback;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.sandbox.SandboxConstants;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -63,10 +63,12 @@ public class AVMContext extends AlfrescoContext
public static final int VERSION_HEAD = -1; public static final int VERSION_HEAD = -1;
// Store properties // Store types to show in the virtualization view
public static QName PROP_WORKFLOWPREVIEW = QName.createQName(NamespaceService.DEFAULT_URI, ".sandbox.workflow.preview"); public static final int ShowNormalStores = 0x0001;
public static QName PROP_AUTHORPREVIEW = QName.createQName(NamespaceService.DEFAULT_URI, ".sandbox.author.preview"); public static final int ShowStagingStores = 0x0002;
public static final int ShowAuthorStores = 0x0004;
public static final int ShowPreviewStores = 0x0008;
// Store, root path and version // Store, root path and version
@@ -80,13 +82,13 @@ public class AVMContext extends AlfrescoContext
private boolean m_virtualView; private boolean m_virtualView;
// Show sandboxes in the virtualization view // Associated AVM filesystem driver
private boolean m_showSandboxes = false;
// associated AVM filesystem driver
private AVMDiskDriver m_avmDriver; private AVMDiskDriver m_avmDriver;
// Virtualization view filtering options
private int m_showOptions;
/** /**
* Class constructor * Class constructor
@@ -118,17 +120,17 @@ public class AVMContext extends AlfrescoContext
* <p>Construct a context for a virtualization view onto all stores/versions within AVM. * <p>Construct a context for a virtualization view onto all stores/versions within AVM.
* *
* @param filesysName String * @param filesysName String
* @param showSandboxes boolean * @param showOptions int
* @param avmDriver AVMDiskDriver * @param avmDriver AVMDiskDriver
*/ */
public AVMContext( String filesysName, boolean showSandboxes, AVMDiskDriver avmDriver) public AVMContext( String filesysName, int showOptions, AVMDiskDriver avmDriver)
{ {
super( filesysName, "VirtualView"); super( filesysName, "VirtualView");
// Enable the virtualization view // Enable the virtualization view
m_virtualView = true; m_virtualView = true;
m_showSandboxes = showSandboxes; m_showOptions = showOptions;
// Save the associated filesystem driver // Save the associated filesystem driver
@@ -176,15 +178,74 @@ public class AVMContext extends AlfrescoContext
} }
/** /**
* Check if sandboxes should be shown in the virtualization view * Check if normal stores should be shown in the virtualization view
* *
* @return boolean * @return boolean
*/ */
public final boolean showSandboxes() public final boolean showNormalStores()
{ {
return m_showSandboxes; return (m_showOptions & ShowNormalStores) != 0 ? true : false;
} }
/**
* Check if author stores should be shown in the virtualization view
*
* @return boolean
*/
public final boolean showAuthorStores()
{
return (m_showOptions & ShowAuthorStores) != 0 ? true : false;
}
/**
* Check if preview stores should be shown in the virtualization view
*
* @return boolean
*/
public final boolean showPreviewStores()
{
return (m_showOptions & ShowPreviewStores) != 0 ? true : false;
}
/**
* Check if staging stores should be shown in the virtualization view
*
* @return boolean
*/
public final boolean showStagingStores()
{
return (m_showOptions & ShowStagingStores) != 0 ? true : false;
}
/**
* Check if the specified store type should be visible
*
* @param storeType int
* @return boolean
*/
public final boolean showStoreType(int storeType)
{
boolean showStore = false;
switch ( storeType)
{
case StoreType.Normal:
showStore = showNormalStores();
break;
case StoreType.WebAuthorMain:
showStore = showAuthorStores();
break;
case StoreType.WebStagingMain:
showStore = showStagingStores();
break;
case StoreType.WebAuthorPreview:
case StoreType.WebStagingPreview:
showStore = showPreviewStores();
break;
}
return showStore;
}
/** /**
* Close the filesystem context * Close the filesystem context
*/ */
@@ -226,43 +287,10 @@ public class AVMContext extends AlfrescoContext
if ( rootState != null) if ( rootState != null)
{ {
// Get the properties for the new store // Delete the root folder file state and recreate it
boolean sandbox = false; fsTable.removeFileState( FileName.DOS_SEPERATOR_STR);
Map<QName, PropertyValue> props = m_avmDriver.getAVMStoreProperties( storeName); // m_avmDriver.findPseudoState( new AVMPath( ""), this);
if ( props.containsKey( PROP_WORKFLOWPREVIEW) || props.containsKey( PROP_AUTHORPREVIEW))
sandbox = true;
// Add a pseudo file for the current store
if ( sandbox == false || showSandboxes() == true)
{
// Add a pseudo folder for the new store
rootState.addPseudoFile( new StorePseudoFile( storeName, FileName.DOS_SEPERATOR_STR + storeName));
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Added pseudo folder for new store " + storeName);
// Send a change notification for the new folder
if ( hasChangeHandler())
{
// Build the filesystem relative path to the new store folder
StringBuilder str = new StringBuilder();
str.append( FileName.DOS_SEPERATOR);
str.append( storeName);
// Send the change notification
getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionAdded, str.toString());
}
}
} }
} }
@@ -306,6 +334,10 @@ public class AVMContext extends AlfrescoContext
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled())
logger.debug( "Removed pseudo folder for purged store " + storeName); logger.debug( "Removed pseudo folder for purged store " + storeName);
// Update the file state modify time
rootState.setLastUpdated( System.currentTimeMillis());
// Send a change notification for the deleted folder // Send a change notification for the deleted folder
if ( hasChangeHandler()) if ( hasChangeHandler())

View File

@@ -25,6 +25,7 @@ package org.alfresco.filesys.avm;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -36,6 +37,7 @@ import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement; import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.alfresco.AlfrescoDiskDriver; import org.alfresco.filesys.alfresco.AlfrescoDiskDriver;
import org.alfresco.filesys.server.SrvSession; import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.core.DeviceContext; import org.alfresco.filesys.server.core.DeviceContext;
import org.alfresco.filesys.server.core.DeviceContextException; import org.alfresco.filesys.server.core.DeviceContextException;
import org.alfresco.filesys.server.core.DeviceInterface; import org.alfresco.filesys.server.core.DeviceInterface;
@@ -58,12 +60,14 @@ import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
import org.alfresco.filesys.server.state.FileState; import org.alfresco.filesys.server.state.FileState;
import org.alfresco.filesys.util.StringList; import org.alfresco.filesys.util.StringList;
import org.alfresco.filesys.util.WildCard; import org.alfresco.filesys.util.WildCard;
import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.avm.CreateStoreTxnListener; import org.alfresco.repo.avm.CreateStoreTxnListener;
import org.alfresco.repo.avm.CreateVersionTxnListener; import org.alfresco.repo.avm.CreateVersionTxnListener;
import org.alfresco.repo.avm.PurgeStoreTxnListener; import org.alfresco.repo.avm.PurgeStoreTxnListener;
import org.alfresco.repo.avm.PurgeVersionTxnListener; import org.alfresco.repo.avm.PurgeVersionTxnListener;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.sandbox.SandboxConstants;
import org.alfresco.service.cmr.avm.AVMBadArgumentException; import org.alfresco.service.cmr.avm.AVMBadArgumentException;
import org.alfresco.service.cmr.avm.AVMExistsException; import org.alfresco.service.cmr.avm.AVMExistsException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
@@ -73,9 +77,17 @@ import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.avm.AVMWrongTypeException; import org.alfresco.service.cmr.avm.AVMWrongTypeException;
import org.alfresco.service.cmr.avm.VersionDescriptor; import org.alfresco.service.cmr.avm.VersionDescriptor;
import org.alfresco.service.cmr.avm.locking.AVMLockingException; import org.alfresco.service.cmr.avm.locking.AVMLockingException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.repository.MimetypeService;
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.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -97,39 +109,44 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Configuration key names // Configuration key names
private static final String KEY_STORE = "storePath"; private static final String KEY_STORE = "storePath";
private static final String KEY_VERSION = "version"; private static final String KEY_VERSION = "version";
private static final String KEY_CREATE = "createStore"; private static final String KEY_CREATE = "createStore";
// AVM path seperator // AVM path seperator
public static final char AVM_SEPERATOR = '/'; public static final char AVM_SEPERATOR = '/';
public static final String AVM_SEPERATOR_STR = "/"; public static final String AVM_SEPERATOR_STR = "/";
// Define client role names
public static final String RoleContentManager = "ContentManager";
public static final String RoleWebProject = "WebProject";
public static final String RoleNotWebAuthor = "NotWebAuthor";
// Content manager web project role
private static final String ROLE_CONTENT_MANAGER = "ContentManager";
// Services and helpers // Services and helpers
private AVMService m_avmService; private AVMService m_avmService;
private TransactionService m_transactionService; private TransactionService m_transactionService;
private MimetypeService m_mimetypeService; private MimetypeService m_mimetypeService;
private AuthenticationComponent m_authComponent; private AuthenticationComponent m_authComponent;
private AuthenticationService m_authService; private AuthenticationService m_authService;
private NodeService m_nodeService;
// AVM listeners // AVM listeners
private CreateStoreTxnListener m_createStoreListener; private CreateStoreTxnListener m_createStoreListener;
private PurgeStoreTxnListener m_purgeStoreListener; private PurgeStoreTxnListener m_purgeStoreListener;
private CreateVersionTxnListener m_createVerListener; private CreateVersionTxnListener m_createVerListener;
private PurgeVersionTxnListener m_purgeVerListener; private PurgeVersionTxnListener m_purgeVerListener;
// Web project store
private String m_webProjectStore;
/** /**
* Default constructor * Default constructor
*/ */
@@ -222,6 +239,16 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
m_mimetypeService = mimetypeService; m_mimetypeService = mimetypeService;
} }
/**
* Set the node service
*
* @param nodeService NodeService
*/
public void setNodeService(NodeService nodeService)
{
m_nodeService = nodeService;
}
/** /**
* Set the create store listener * Set the create store listener
* *
@@ -266,6 +293,16 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
m_purgeVerListener = purgeVersionListener; m_purgeVerListener = purgeVersionListener;
} }
/**
* Set the web project store
*
* @param webStore String
*/
public void setWebProjectStore(String webStore)
{
m_webProjectStore = webStore;
}
/** /**
* Parse and validate the parameter string and create a device context object for this instance of the shared * Parse and validate the parameter string and create a device context object for this instance of the shared
* device. * device.
@@ -307,13 +344,48 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
ConfigElement virtElem = cfg.getChild("virtualView"); ConfigElement virtElem = cfg.getChild("virtualView");
if (virtElem != null) if (virtElem != null)
{ {
// Check if sandboxes should be shown in the virtualization view // Check if virtualization view show options have been specified
boolean showSandboxes = cfg.getChild("showAllSandboxes") != null ? true : false; int showOptions = AVMContext.ShowStagingStores + AVMContext.ShowAuthorStores;
String showAttr = virtElem.getAttribute( "stores");
if ( showAttr != null)
{
// Split the show options string
StringTokenizer tokens = new StringTokenizer( showAttr, ",");
StringList optList = new StringList();
while ( tokens.hasMoreTokens())
optList.addString( tokens.nextToken().trim().toLowerCase());
// Build the show options mask
showOptions = 0;
if ( optList.containsString("normal"))
showOptions += AVMContext.ShowNormalStores;
if ( optList.containsString("author"))
showOptions += AVMContext.ShowAuthorStores;
if ( optList.containsString("preview"))
showOptions += AVMContext.ShowPreviewStores;
if ( optList.containsString("staging"))
showOptions += AVMContext.ShowStagingStores;
}
else if ( cfg.getChild("showAllSandboxes") != null)
{
// Old style show options
showOptions = AVMContext.ShowNormalStores + AVMContext.ShowAuthorStores +
AVMContext.ShowPreviewStores + AVMContext.ShowStagingStores;
}
// Create the context // Create the context
context = new AVMContext(name, showSandboxes, this); context = new AVMContext(name, showOptions, this);
// Enable file state caching // Enable file state caching
@@ -327,6 +399,10 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
m_createVerListener.addCallback(context); m_createVerListener.addCallback(context);
m_purgeVerListener.addCallback(context); m_purgeVerListener.addCallback(context);
// Create the file state for the root path, this will build the store pseudo folder list
findPseudoState( new AVMPath( ""), context);
} }
else else
{ {
@@ -518,7 +594,9 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
} }
} }
} }
// Return the context for this shared filesystem // Return the context for this shared filesystem
return context; return context;
} }
finally finally
@@ -673,13 +751,14 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
/** /**
* Build the full store path for a file/folder using the share relative path * Build the full store path for a file/folder using the share relative path
* *
* @param ctx * @param ctx AVMContext
* AVMContext * @param path String
* @param path * @param sess SrvSession
* String
* @return AVMPath * @return AVMPath
* @exception AccessDeniedException
*/ */
protected final AVMPath buildStorePath(AVMContext ctx, String path) protected final AVMPath buildStorePath(AVMContext ctx, String path, SrvSession sess)
throws AccessDeniedException
{ {
// Check if the AVM filesystem is a normal or virtualization view // Check if the AVM filesystem is a normal or virtualization view
@@ -690,6 +769,10 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Create a path for the virtualization view // Create a path for the virtualization view
avmPath = new AVMPath(path); avmPath = new AVMPath(path);
// Check that the user has access to the path
checkPathAccess( avmPath, ctx, sess);
} }
else else
{ {
@@ -771,7 +854,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the relative path to a store path // Convert the relative path to a store path
AVMPath storePath = buildStorePath(ctx, paths[0]); AVMPath storePath = buildStorePath(ctx, paths[0], sess);
// DEBUG // DEBUG
@@ -839,7 +922,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the relative path to a store path // Convert the relative path to a store path
AVMPath storePath = buildStorePath(ctx, paths[0]); AVMPath storePath = buildStorePath(ctx, paths[0], sess);
// DEBUG // DEBUG
@@ -871,7 +954,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Get the new file details // Get the new file details
AVMPath fileStorePath = buildStorePath(ctx, params.getPath()); AVMPath fileStorePath = buildStorePath(ctx, params.getPath(), sess);
AVMNodeDescriptor nodeDesc = m_avmService.lookup(fileStorePath.getVersion(), fileStorePath.getAVMPath()); AVMNodeDescriptor nodeDesc = m_avmService.lookup(fileStorePath.getVersion(), fileStorePath.getAVMPath());
if (nodeDesc != null) if (nodeDesc != null)
@@ -933,7 +1016,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the relative path to a store path // Convert the relative path to a store path
AVMContext ctx = (AVMContext) tree.getContext(); AVMContext ctx = (AVMContext) tree.getContext();
AVMPath storePath = buildStorePath(ctx, dir); AVMPath storePath = buildStorePath(ctx, dir, sess);
// DEBUG // DEBUG
@@ -1001,7 +1084,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the relative path to a store path // Convert the relative path to a store path
AVMContext ctx = (AVMContext) tree.getContext(); AVMContext ctx = (AVMContext) tree.getContext();
AVMPath storePath = buildStorePath(ctx, name); AVMPath storePath = buildStorePath(ctx, name, sess);
// DEBUG // DEBUG
@@ -1067,8 +1150,22 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the relative path to a store path // Convert the relative path to a store path
AVMContext ctx = (AVMContext) tree.getContext(); AVMContext ctx = (AVMContext) tree.getContext();
AVMPath storePath = buildStorePath(ctx, name); AVMPath storePath = null;
try
{
storePath = buildStorePath(ctx, name, sess);
}
catch ( AccessDeniedException ex)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("File exists check, path=" + name + " Access denied");
return FileStatus.NotExist;
}
// DEBUG // DEBUG
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
@@ -1173,8 +1270,8 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the relative path to a store path // Convert the relative path to a store path
AVMContext ctx = (AVMContext) tree.getContext(); AVMContext ctx = (AVMContext) tree.getContext();
AVMPath storePath = buildStorePath( ctx, name); AVMPath storePath = buildStorePath( ctx, name, sess);
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled())
@@ -1260,9 +1357,12 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Mark the file/folder as read-only if not the head version // Mark the file/folder as read-only if not the head version
if ( ctx.isVersion() != AVMContext.VERSION_HEAD) if ( ctx.isVersion() != AVMContext.VERSION_HEAD || storePath.isReadOnlyAccess())
attr += FileAttribute.ReadOnly; attr += FileAttribute.ReadOnly;
if ( attr == 0)
attr = FileAttribute.NTNormal;
info.setFileAttributes( attr); info.setFileAttributes( attr);
// Set the file id // Set the file id
@@ -1326,7 +1426,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the relative path to a store path // Convert the relative path to a store path
AVMContext ctx = (AVMContext) tree.getContext(); AVMContext ctx = (AVMContext) tree.getContext();
AVMPath storePath = buildStorePath(ctx, params.getPath()); AVMPath storePath = buildStorePath(ctx, params.getPath(), sess);
// DEBUG // DEBUG
@@ -1492,8 +1592,8 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the parent paths to store paths // Convert the parent paths to store paths
AVMPath oldAVMPath = buildStorePath(ctx, oldPaths[0]); AVMPath oldAVMPath = buildStorePath(ctx, oldPaths[0], sess);
AVMPath newAVMPath = buildStorePath(ctx, newPaths[0]); AVMPath newAVMPath = buildStorePath(ctx, newPaths[0], sess);
// DEBUG // DEBUG
@@ -1631,7 +1731,21 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Build the store path to the folder being searched // Build the store path to the folder being searched
AVMPath storePath = buildStorePath(avmCtx, paths[0]); AVMPath storePath = null;
try
{
storePath = buildStorePath(avmCtx, paths[0], sess);
}
catch ( AccessDeniedException ex)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Start search access denied");
throw new FileNotFoundException("Access denied");
}
// Check if the filesystem is the virtualization view // Check if the filesystem is the virtualization view
@@ -1649,7 +1763,12 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
{ {
// Get the pseudo file list for the parent directory // Get the pseudo file list for the parent directory
PseudoFileList searchList = fstate.getPseudoFileList(); PseudoFileList searchList = null;
if ( storePath.isLevel() == AVMPath.LevelId.Root)
searchList = filterPseudoFolders(avmCtx, sess, storePath, fstate);
else
searchList = fstate.getPseudoFileList();
// Check if the pseudo file list is valid // Check if the pseudo file list is valid
@@ -1664,7 +1783,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// folder listing // folder listing
WildCard wildCardFilter = new WildCard(paths[1], false); WildCard wildCardFilter = new WildCard(paths[1], false);
return new PseudoFileListSearchContext(searchList, attrib, wildCardFilter); return new PseudoFileListSearchContext(searchList, attrib, wildCardFilter, storePath.isReadOnlyAccess());
} }
else else
{ {
@@ -1678,7 +1797,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
PseudoFileList singleList = new PseudoFileList(); PseudoFileList singleList = new PseudoFileList();
singleList.addFile(pseudoFile); singleList.addFile(pseudoFile);
return new PseudoFileListSearchContext(singleList, attrib, null); return new PseudoFileListSearchContext(singleList, attrib, null, storePath.isReadOnlyAccess());
} }
} }
} }
@@ -1694,7 +1813,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
PseudoFileList metaFiles = new PseudoFileList(); PseudoFileList metaFiles = new PseudoFileList();
return new PseudoFileListSearchContext(metaFiles, attrib, null); return new PseudoFileListSearchContext(metaFiles, attrib, null, storePath.isReadOnlyAccess());
} }
} }
@@ -1707,8 +1826,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
{ {
// Get the file listing for the folder // Get the file listing for the folder
AVMNodeDescriptor[] fileList = m_avmService.getDirectoryListingArray(storePath.getVersion(), storePath AVMNodeDescriptor[] fileList = m_avmService.getDirectoryListingArray(storePath.getVersion(), storePath.getAVMPath(), false);
.getAVMPath(), false);
// Create the search context // Create the search context
@@ -1724,14 +1842,26 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// folder listing // folder listing
WildCard wildCardFilter = new WildCard(paths[1], false); WildCard wildCardFilter = new WildCard(paths[1], false);
context = new AVMSearchContext(fileList, attrib, wildCardFilter, storePath.getRelativePath()); context = new AVMSearchContext(fileList, attrib, wildCardFilter, storePath.getRelativePath(), storePath.isReadOnlyAccess());
} }
} }
else else
{ {
// Single file/folder search, convert the path to a store path // Single file/folder search, convert the path to a store path
storePath = buildStorePath(avmCtx, searchPath); try
{
storePath = buildStorePath(avmCtx, searchPath, sess);
}
catch ( AccessDeniedException ex)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Start search access denied");
throw new FileNotFoundException("Access denied");
}
// Get the single file/folder details // Get the single file/folder details
@@ -1741,7 +1871,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
{ {
// Create the search context for the single file/folder // Create the search context for the single file/folder
context = new AVMSingleFileSearchContext(nodeDesc, storePath.getRelativePath()); context = new AVMSingleFileSearchContext(nodeDesc, storePath.getRelativePath(), storePath.isReadOnlyAccess());
} }
} }
@@ -2074,7 +2204,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
* AVMContext * AVMContext
* @return FileState * @return FileState
*/ */
private final FileState findPseudoState(AVMPath avmPath, AVMContext avmCtx) protected final FileState findPseudoState(AVMPath avmPath, AVMContext avmCtx)
{ {
// Make sure the is to a pseudo file/folder // Make sure the is to a pseudo file/folder
@@ -2114,30 +2244,185 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
{ {
// Add pseudo files for the stores // Add pseudo files for the stores
boolean sandbox = false;
for ( AVMStoreDescriptor storeDesc : storeList) for ( AVMStoreDescriptor storeDesc : storeList)
{ {
// Get the properties for the current store // Get the properties for the current store
String storeName = storeDesc.getName();
Map<QName, PropertyValue> props = m_avmService.getStoreProperties( storeName);
Map<QName, PropertyValue> props = m_avmService.getStoreProperties( storeDesc.getName()); // Check if the store is a main web project
if ( props.containsKey( AVMContext.PROP_WORKFLOWPREVIEW) || props.containsKey( AVMContext.PROP_AUTHORPREVIEW)) if ( props.containsKey( SandboxConstants.PROP_SANDBOX_STAGING_MAIN))
sandbox = true; {
// Get the noderef for the web project
PropertyValue prop = props.get( SandboxConstants.PROP_WEB_PROJECT_NODE_REF);
if ( prop != null) {
// Get the web project noderef
NodeRef webNodeRef = new NodeRef( prop.getStringValue());
// Create the web project pseudo folder
WebProjectStorePseudoFile webProjFolder = new WebProjectStorePseudoFile( storeDesc, FileName.DOS_SEPERATOR_STR + storeName, webNodeRef);
fstate.addPseudoFile( webProjFolder);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Found web project " + webProjFolder.getFileName());
// Get the list of content managers for this web project
List<ChildAssociationRef> mgrAssocs = m_nodeService.getChildAssocs( webNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
for ( ChildAssociationRef mgrRef : mgrAssocs)
{
// Get the child node and see if it is a content manager association
NodeRef childRef = mgrRef.getChildRef();
if ( m_nodeService.getProperty( childRef, WCMAppModel.PROP_WEBUSERROLE).equals(ROLE_CONTENT_MANAGER))
{
// Get the user name add it to the web project pseudo folder
String userName = (String) m_nodeService.getProperty( childRef, WCMAppModel.PROP_WEBUSERNAME);
webProjFolder.addUserRole( userName, WebProjectStorePseudoFile.RoleContentManager);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug(" Added content manager " + userName);
}
}
}
}
else else
sandbox = false; {
// Check if this store is a web project sandbox
int storeType = StoreType.Normal;
String webProjName = null;
String userName = null;
if ( props.containsKey( SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN))
{
// Sandbox store, linked to a web project
storeType = StoreType.WebAuthorMain;
// Get the associated web project name
// DEBUG webProjName = props.get( SandboxConstants.PROP_WEBSITE_NAME).getStringValue();
if ( logger.isDebugEnabled())
logger.debug( "Store " + storeDesc.getName() + ", sandbox=" + sandbox);
// Add a pseudo file for the current store
if ( sandbox == false || avmCtx.showSandboxes() == true) // Get the user name from teh store name
fstate.addPseudoFile( new StorePseudoFile( storeDesc, FileName.DOS_SEPERATOR_STR + storeDesc.getName()));
userName = storeName.substring( webProjName.length() + 2);
}
else if ( props.containsKey( SandboxConstants.PROP_SANDBOX_AUTHOR_PREVIEW))
{
// Author preview sandbox store, linked to a web project
storeType = StoreType.WebAuthorPreview;
// Get the associated web project name
String projPlusUser = storeName.substring( 0, storeName.length() - "--preview".length());
int pos = projPlusUser.lastIndexOf("--");
if ( pos != -1)
{
webProjName = projPlusUser.substring( 0, pos);
userName = projPlusUser.substring(pos + 2);
}
}
else if ( props.containsKey( SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW))
{
// Staging preview sandbox store, linked to a web project
storeType = StoreType.WebStagingPreview;
}
else if ( props.containsKey( SandboxConstants.PROP_SANDBOX_STAGING_PREVIEW))
{
// Staging preview sandbox store, linked to a web project
storeType = StoreType.WebStagingPreview;
// Get the associated web project name
webProjName = storeName.substring( 0, storeName.length() - "--preview".length());
}
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Store " + storeDesc.getName() + ", type=" + StoreType.asString( storeType) + ", webproj=" + webProjName + ", username=" + userName);
// Add a pseudo file for the current store
if ( avmCtx.showStoreType( storeType))
{
// Create the pseudo folder for the store
StorePseudoFile storeFolder = new StorePseudoFile( storeDesc, FileName.DOS_SEPERATOR_STR + storeName, storeType);
if ( storeType != StoreType.Normal)
{
storeFolder.setWebProject( webProjName);
storeFolder.setUserName( userName);
}
// Add the store pseudo folder to the root folder file list
fstate.addPseudoFile( storeFolder);
}
}
} }
} }
// Scan the pseudo folder list and add all publisher/reviewer user names to the web project roles list
PseudoFileList folderList = fstate.getPseudoFileList();
if ( folderList != null && folderList.numberOfFiles() > 0)
{
// Scan the pseudo folder list
for ( int i = 0; i < folderList.numberOfFiles(); i++)
{
// Check if the current pseduo file is a store folder
if ( folderList.getFileAt( i) instanceof StorePseudoFile)
{
// Check if the store has an associated web project
StorePseudoFile curFile = (StorePseudoFile) folderList.getFileAt( i);
if ( curFile.hasWebProject())
{
// Find the associated web project pseudo folder
WebProjectStorePseudoFile webProj = (WebProjectStorePseudoFile) folderList.findFile( curFile.getWebProject(), true);
// Strip the web project name from the sandbox store name and extract the user name.
// Add the user as a publisher/reviewer to the web project roles list
String userName = curFile.getFileName().substring( webProj.getFileName().length() + 2);
// If the user does not have a content manager role then add as a publisher
if ( webProj.getUserRole( userName) == WebProjectStorePseudoFile.RoleNone)
{
webProj.addUserRole( userName, WebProjectStorePseudoFile.RolePublisher);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Added publisher " + userName + " to " + webProj.getFileName());
}
}
}
}
}
} }
break; break;
@@ -2406,4 +2691,219 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
} }
} }
} }
/**
* Check that the user has access to the path
*
* @param avmPath AVMPath
* @param avmCtx AVMContext
* @param sess SrvSession
* @exception AccessDeniedException
*/
private final void checkPathAccess( AVMPath avmPath, AVMContext avmCtx, SrvSession sess)
throws AccessDeniedException {
// Only enforce access checks on virtualization views
if ( avmCtx.isVirtualizationView() == false)
return;
// Get the client details for the session
ClientInfo cInfo = sess.getClientInformation();
if ( cInfo == null || cInfo.getUserName() == null || cInfo.getUserName().length() == 0)
throw new AccessDeniedException();
// Allow access to the root folder
if ( avmPath.isLevel() == AVMPath.LevelId.Root)
return;
// Admin user has full access
if ( cInfo.getUserName().equalsIgnoreCase( m_authComponent.getSystemUserName()))
return;
// Get root file state, get the store pseudo folder details
FileState rootState = avmCtx.getStateTable().findFileState( FileName.DOS_SEPERATOR_STR);
if ( rootState == null){
// Recreate the root file state, new stores may have been added
rootState = findPseudoState( new AVMPath( FileName.DOS_SEPERATOR_STR), avmCtx);
}
// Check if there are any store pseudo folders
if ( rootState != null && rootState.hasPseudoFiles())
{
PseudoFile pseudoFolder = rootState.getPseudoFileList().findFile( avmPath.getStoreName(), false);
if ( pseudoFolder != null)
{
// Check if the pseudo folder is a web project folder or sandbox within a web project
if ( pseudoFolder instanceof WebProjectStorePseudoFile)
{
// Check the users role within the web project
WebProjectStorePseudoFile webFolder = (WebProjectStorePseudoFile) pseudoFolder;
int role = webFolder.getUserRole( cInfo.getUserName());
if ( role == WebProjectStorePseudoFile.RoleNone)
{
// User does not have access to this web project
throw new AccessDeniedException("User " + cInfo.getUserName() + " has no access to web project, " + webFolder.getFileName());
}
else if ( role == WebProjectStorePseudoFile.RolePublisher)
{
// Only allow read-only access to the staging area
avmPath.setReadOnlyAccess( true);
}
}
else if ( pseudoFolder instanceof StorePseudoFile)
{
// Check the store type
StorePseudoFile storeFolder = (StorePseudoFile) pseudoFolder;
if ( storeFolder.isStoreType() == StoreType.Normal)
return;
else if ( storeFolder.hasWebProject())
{
// Get the web project that the sandbox is linked to
WebProjectStorePseudoFile webFolder = (WebProjectStorePseudoFile) rootState.getPseudoFileList().findFile( storeFolder.getWebProject(), false);
int role = webFolder.getUserRole( cInfo.getUserName());
if ( role == WebProjectStorePseudoFile.RoleNone)
{
// User does not have access to this web project
throw new AccessDeniedException("User " + cInfo.getUserName() + " has no access to web project, " + webFolder.getFileName() + "/" + storeFolder.getFileName());
}
else if ( role == WebProjectStorePseudoFile.RolePublisher &&
storeFolder.getUserName().equalsIgnoreCase( cInfo.getUserName()) == false)
{
// User does not have access to this web project
throw new AccessDeniedException("User " + cInfo.getUserName() + " has no access to web project, " + webFolder.getFileName() + "/" + storeFolder.getFileName());
}
}
}
}
}
else
{
// Store does not exist
throw new AccessDeniedException("Store does not exist, " + avmPath.getStoreName());
}
// DEBUG
if (logger.isDebugEnabled())
logger.debug( "Check access " + avmPath);
}
/**
* Filter the list of pseudo folders returned in a search
*
* @param avmCtx AVMContext
* @param sess SrvSession
* @param avmPath AVMPath
* @param fstate FileState
* @return PseudoFileList
*/
private final PseudoFileList filterPseudoFolders( AVMContext avmCtx, SrvSession sess, AVMPath avmPath, FileState fstate)
{
// Check if the root folder file state has any store pseudo folders
if ( fstate.hasPseudoFiles() == false)
return null;
// Get the client details for the session
ClientInfo cInfo = sess.getClientInformation();
if ( cInfo == null || cInfo.getUserName() == null || cInfo.getUserName().length() == 0)
return null;
// Check for the admin user, no need to filter the list
PseudoFileList fullList = fstate.getPseudoFileList();
if ( cInfo.getUserName().equalsIgnoreCase( m_authComponent.getSystemUserName()))
return fullList;
// Create a filtered list of store pseudo folders that the user has access to
PseudoFileList filterList = new PseudoFileList();
for ( int i = 0; i < fullList.numberOfFiles(); i++)
{
// Get the current store pseudo folder
PseudoFile pseudoFolder = fullList.getFileAt( i);
// Check if the pseudo folder is a web project folder or sandbox within a web project
if ( pseudoFolder instanceof WebProjectStorePseudoFile)
{
// Check the users role within the web project
WebProjectStorePseudoFile webFolder = (WebProjectStorePseudoFile) pseudoFolder;
if ( avmCtx.showStagingStores() && webFolder.getUserRole( cInfo.getUserName()) != WebProjectStorePseudoFile.RoleNone)
{
// User has access to this store
filterList.addFile( pseudoFolder);
}
}
else if ( pseudoFolder instanceof StorePseudoFile)
{
// Check if the store type should be included in the visible list
StorePseudoFile storeFolder = (StorePseudoFile) pseudoFolder;
if ( avmCtx.showStoreType( storeFolder.isStoreType()))
{
// Check if the user has access to this store
if ( storeFolder.hasWebProject())
{
// Get the web project that the sandbox is linked to
WebProjectStorePseudoFile webFolder = (WebProjectStorePseudoFile) fullList.findFile( storeFolder.getWebProject(), false);
int role = webFolder.getUserRole( cInfo.getUserName());
if ( role == WebProjectStorePseudoFile.RoleContentManager && avmCtx.showStoreType( storeFolder.isStoreType()))
{
// User is a content manager, allow access to the store
filterList.addFile( storeFolder);
}
else if ( role == WebProjectStorePseudoFile.RolePublisher && avmCtx.showStoreType( storeFolder.isStoreType()))
{
// Allow access if the user owns the current folder
if ( storeFolder.getUserName().equalsIgnoreCase( cInfo.getUserName()))
filterList.addFile( storeFolder);
}
}
else if ( avmCtx.showNormalStores())
{
// Store is not linked to a web project, allow access to the store
filterList.addFile( storeFolder);
}
}
}
}
// Return the filtered list
return filterList;
}
} }

View File

@@ -86,6 +86,10 @@ public class AVMPath {
private String m_avmPath; private String m_avmPath;
// Path is read-only access
private boolean m_readOnly;
/** /**
* Default constructor * Default constructor
*/ */
@@ -132,6 +136,15 @@ public class AVMPath {
{ {
return m_levelId; return m_levelId;
} }
/**
* Check if the path is read-only
*
* @return boolean
*/
public final boolean isReadOnlyAccess() {
return m_readOnly;
}
/** /**
* Return the store name * Return the store name
@@ -596,6 +609,16 @@ public class AVMPath {
return fid; return fid;
} }
/**
* Set the path access, true for read-only access
*
* @param access boolean
*/
public final void setReadOnlyAccess( boolean readOnly)
{
m_readOnly = readOnly;
}
/** /**
* Return the AVM path details as a string * Return the AVM path details as a string
@@ -676,6 +699,10 @@ public class AVMPath {
str.append(getAVMPath()); str.append(getAVMPath());
break; break;
} }
if ( isReadOnlyAccess())
str.append("-ReadOnly");
str.append("]"); str.append("]");
return str.toString(); return str.toString();

View File

@@ -56,6 +56,10 @@ public class AVMSearchContext extends SearchContext {
private String m_parentPath; private String m_parentPath;
// Mark all files/folders as read-only
private boolean m_readOnly;
/** /**
* Class constructor * Class constructor
* *
@@ -63,8 +67,9 @@ public class AVMSearchContext extends SearchContext {
* @param attrib int * @param attrib int
* @param filter WildCard * @param filter WildCard
* @param parentPath String * @param parentPath String
* @param readOnly boolean
*/ */
public AVMSearchContext( AVMNodeDescriptor[] fileList, int attrib, WildCard filter, String parentPath) public AVMSearchContext( AVMNodeDescriptor[] fileList, int attrib, WildCard filter, String parentPath, boolean readOnly)
{ {
m_attrib = attrib; m_attrib = attrib;
m_filter = filter; m_filter = filter;
@@ -73,6 +78,8 @@ public class AVMSearchContext extends SearchContext {
m_parentPath = parentPath; m_parentPath = parentPath;
if ( m_parentPath != null && m_parentPath.endsWith( FileName.DOS_SEPERATOR_STR) == false) if ( m_parentPath != null && m_parentPath.endsWith( FileName.DOS_SEPERATOR_STR) == false)
m_parentPath = m_parentPath + FileName.DOS_SEPERATOR_STR; m_parentPath = m_parentPath + FileName.DOS_SEPERATOR_STR;
m_readOnly = readOnly;
} }
/** /**
@@ -177,6 +184,12 @@ public class AVMSearchContext extends SearchContext {
curFile.getName().equalsIgnoreCase( "Desktop.ini") || curFile.getName().equalsIgnoreCase( "Desktop.ini") ||
curFile.getName().equalsIgnoreCase( "Thumbs.db")) curFile.getName().equalsIgnoreCase( "Thumbs.db"))
attr += FileAttribute.Hidden; attr += FileAttribute.Hidden;
if ( isReadOnly())
attr += FileAttribute.ReadOnly;
if ( attr == 0)
attr = FileAttribute.NTNormal;
info.setFileAttributes( attr); info.setFileAttributes( attr);
@@ -293,4 +306,24 @@ public class AVMSearchContext extends SearchContext {
m_fileIdx = curFileIdx; m_fileIdx = curFileIdx;
return false; return false;
} }
/**
* Check if all files/folders returned by the search should be marked as read-only
*
* @return boolean
*/
public final boolean isReadOnly()
{
return m_readOnly;
}
/**
* Set all files/folders returned by the search as read-only
*
* @param readOnly boolean
*/
public final void setReadOnly( boolean readOnly)
{
m_readOnly = readOnly;
}
} }

View File

@@ -49,16 +49,23 @@ public class AVMSingleFileSearchContext extends SearchContext {
private String m_relativePath; private String m_relativePath;
// Mark thel file/folder as read-only
private boolean m_readOnly;
/** /**
* Class constructor * Class constructor
* *
* @param fileDetails AVMNodeDescriptor * @param fileDetails AVMNodeDescriptor
* @param relPath String * @param relPath String
* @param readOnly boolean
*/ */
public AVMSingleFileSearchContext( AVMNodeDescriptor fileDetails, String relPath) public AVMSingleFileSearchContext( AVMNodeDescriptor fileDetails, String relPath, boolean readOnly)
{ {
m_fileDetails = fileDetails; m_fileDetails = fileDetails;
m_relativePath = relPath; m_relativePath = relPath;
m_readOnly = readOnly;
} }
/** /**
@@ -112,6 +119,9 @@ public class AVMSingleFileSearchContext extends SearchContext {
m_fileDetails.getName().equalsIgnoreCase( "Desktop.ini") || m_fileDetails.getName().equalsIgnoreCase( "Desktop.ini") ||
m_fileDetails.getName().equalsIgnoreCase( "Thumbs.db")) m_fileDetails.getName().equalsIgnoreCase( "Thumbs.db"))
attr += FileAttribute.Hidden; attr += FileAttribute.Hidden;
if ( m_readOnly == true)
attr += FileAttribute.ReadOnly;
info.setFileAttributes( attr); info.setFileAttributes( attr);
info.setFileId( m_relativePath.hashCode()); info.setFileId( m_relativePath.hashCode());

View File

@@ -52,18 +52,24 @@ public class PseudoFileListSearchContext extends SearchContext {
private WildCard m_filter; private WildCard m_filter;
// Mark all files/folders as read-only
private boolean m_readOnly;
/** /**
* Class constructor * Class constructor
* *
* @param fileList PseudoFileList * @param fileList PseudoFileList
* @param attrib int * @param attrib int
* @param filter WildCard * @param filter WildCard
* @param readOnly boolean
*/ */
public PseudoFileListSearchContext( PseudoFileList fileList, int attrib, WildCard filter) public PseudoFileListSearchContext( PseudoFileList fileList, int attrib, WildCard filter, boolean readOnly)
{ {
m_attrib = attrib; m_attrib = attrib;
m_filter = filter; m_filter = filter;
m_fileList = fileList; m_fileList = fileList;
m_readOnly = readOnly;
} }
/** /**
@@ -176,6 +182,11 @@ public class PseudoFileListSearchContext extends SearchContext {
curFile.getFileName().equalsIgnoreCase( "Desktop.ini") || curFile.getFileName().equalsIgnoreCase( "Desktop.ini") ||
curFile.getFileName().equalsIgnoreCase( "Thumbs.db")) curFile.getFileName().equalsIgnoreCase( "Thumbs.db"))
attr += FileAttribute.Hidden; attr += FileAttribute.Hidden;
// Check if the file/folder should be marked as read-only
if ( m_readOnly && pfInfo.isReadOnly() == false)
attr += FileAttribute.ReadOnly;
info.setFileAttributes( attr); info.setFileAttributes( attr);
info.setFileId( pfInfo.getFileId()); info.setFileId( pfInfo.getFileId());

View File

@@ -40,13 +40,26 @@ import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
*/ */
public class StorePseudoFile extends PseudoFile { public class StorePseudoFile extends PseudoFile {
// Store type
private int m_storeType = StoreType.Normal;
// Web project this sandbox links to, or null if this store is not linked
private String m_webProject;
// User name if this is an author sandbox for a web project
private String m_userName;
/** /**
* Class constructor * Class constructor
* *
* @param storeDesc AVMStoreDescriptor * @param storeDesc AVMStoreDescriptor
* @param relPath String * @param relPath String
* @param storeType int
*/ */
public StorePseudoFile( AVMStoreDescriptor storeDesc, String relPath) public StorePseudoFile( AVMStoreDescriptor storeDesc, String relPath, int storeType)
{ {
super( storeDesc.getName(), FileAttribute.Directory + FileAttribute.ReadOnly); super( storeDesc.getName(), FileAttribute.Directory + FileAttribute.ReadOnly);
@@ -63,6 +76,8 @@ public class StorePseudoFile extends PseudoFile {
fInfo.setFileId( relPath.hashCode()); fInfo.setFileId( relPath.hashCode());
setFileInfo( fInfo); setFileInfo( fInfo);
setStoreType( storeType);
} }
/** /**
@@ -118,4 +133,84 @@ public class StorePseudoFile extends PseudoFile {
public FileInfo getFileInfo() { public FileInfo getFileInfo() {
return getInfo(); return getInfo();
} }
/**
* Return the store type
*
* @return int
*/
public final int isStoreType()
{
return m_storeType;
}
/**
* Check if this store is linked to a web project
*
* @return boolean
*/
public final boolean hasWebProject()
{
return m_webProject != null ? true : false;
}
/**
* Get the web project that this store links to, or null if not linked
*
* @return String
*/
public final String getWebProject()
{
return m_webProject;
}
/**
* Set the web project that this store is linked to
*
* @param webProject String
*/
public final void setWebProject(String webProject)
{
m_webProject = webProject;
}
/**
* Check if this store is an author sandbox
*
* @return boolean
*/
public final boolean hasUserName()
{
return m_userName != null ? true : false;
}
/**
* Get the owner of this sandbox
*
* @return String
*/
public final String getUserName()
{
return m_userName;
}
/**
* Set the owner of this sandbox
*
* @param userName String
*/
public final void setUserName(String userName)
{
m_userName = userName;
}
/**
* Set the store type
*
* @param storeType int
*/
public final void setStoreType(int storeType)
{
m_storeType = storeType;
}
} }

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2005-2006 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.filesys.avm;
/**
* Store Types Class
*
* @author gkspencer
*/
public class StoreType {
// Store types
public static final int Normal = 0;
// Web project store types
public static final int WebAuthorMain = 1;
public static final int WebAuthorPreview = 2;
public static final int WebStagingPreview = 3;
public static final int WebStagingMain = 4;
// Store type strings
private static final String[] _types = { "Normal", "AuthorMain", "AuthorPreview", "StagingPreview", "StagingMain" };
/**
* Return a store type as a string
*
* @param typ int
* @return String
*/
public final static String asString( int typ)
{
if ( typ < 0 || typ > _types.length)
return "Invalid";
return _types[ typ];
}
}

View File

@@ -0,0 +1,190 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.avm;
import java.util.Hashtable;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Web Project Store Pseudo File Class
*
* <p>Represents an AVM store as a folder.
*
* @author gkspencer
*/
public class WebProjectStorePseudoFile extends StorePseudoFile {
// Store/web project user access roles
public static final int RoleNone = 0;
public static final int RolePublisher = 1;
public static final int RoleContentManager = 2;
// Node ref for this store
private NodeRef m_noderef;
// List of users that are content managers/publishers for this web project store
private Hashtable<String, Integer> m_users;
/**
* Class constructor
*
* @param storeDesc AVMStoreDescriptor
* @param relPath String
* @param nodeRef NodeRef
*/
public WebProjectStorePseudoFile( AVMStoreDescriptor storeDesc, String relPath, NodeRef nodeRef)
{
super( storeDesc, relPath, StoreType.WebStagingMain);
// Create static file information from the store details
FileInfo fInfo = new FileInfo( storeDesc.getName(), 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
fInfo.setCreationDateTime( storeDesc.getCreateDate());
fInfo.setModifyDateTime( storeDesc.getCreateDate());
fInfo.setAccessDateTime( storeDesc.getCreateDate());
fInfo.setChangeDateTime( storeDesc.getCreateDate());
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
setFileInfo( fInfo);
// Set the associated node ref for the web project
m_noderef = nodeRef;
}
/**
* Class constructor
*
* @param storeName String
* @param relPath String
* @param nodeRef NodeRef
*/
public WebProjectStorePseudoFile( String storeName, String relPath, NodeRef nodeRef)
{
super( storeName, relPath);
// Create static file information from the store details
FileInfo fInfo = new FileInfo( storeName, 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
long timeNow = System.currentTimeMillis();
fInfo.setCreationDateTime( timeNow);
fInfo.setModifyDateTime( timeNow);
fInfo.setAccessDateTime( timeNow);
fInfo.setChangeDateTime( timeNow);
fInfo.setPath( relPath);
fInfo.setFileId( relPath.hashCode());
setFileInfo( fInfo);
// Set the associated node ref for the web project
m_noderef = nodeRef;
}
/**
* Check if the associated node ref is valid
*
* @return boolean
*/
public final boolean hasNodeRef()
{
return m_noderef != null ? true : false;
}
/**
* Get the associated node ref for the store
*
* @return NodeRef
*/
public final NodeRef getNodeRef()
{
return m_noderef;
}
/**
* Set the associated node ref for the store
*
* @param node NodeRef
*/
public final void setNodeRef(NodeRef node)
{
m_noderef = node;
}
/**
* Return the role for the specified user within this web project
*
* @param userName String
* @return int
*/
public final int getUserRole(String userName)
{
if ( m_users == null)
return RoleNone;
Integer role = m_users.get( userName);
return role != null ? role.intValue() : RoleNone;
}
/**
* Add a user role for this web project
*
* @param userName String
* @param role int
*/
public final void addUserRole(String userName, int role)
{
if ( m_users == null)
m_users = new Hashtable<String, Integer>();
m_users.put(userName, new Integer(role));
}
/**
* Remove a user role for this project
*
* @param userName String
*/
public final void removeUserRole(String userName)
{
if ( m_users != null)
m_users.remove(userName);
}
}

View File

@@ -95,6 +95,10 @@ public class FileState
private PseudoFileList m_pseudoFiles; private PseudoFileList m_pseudoFiles;
// Last updated time
private long m_lastUpdate;
/** /**
* Class constructor * Class constructor
* *
@@ -357,6 +361,26 @@ public class FileState
m_pseudoFiles = new PseudoFileList(); m_pseudoFiles = new PseudoFileList();
m_pseudoFiles.addFile( pfile); m_pseudoFiles.addFile( pfile);
} }
/**
* Return the last updated time
*
* @return long
*/
public final long getLastUpdated()
{
return m_lastUpdate;
}
/**
* Set the last updated time
*
* @param updateTime long
*/
public final void setLastUpdated(long updateTime)
{
m_lastUpdate = updateTime;
}
/** /**
* Set the file status * Set the file status

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.admin.patch.impl;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
/**
* @author Kevin Roast
*/
public class AVMFormsPropertyTokenisationPatch extends BaseReindexingPatch
{
private static final String MSG_SUCCESS = "patch.avmFormPropertyIdentifier.result";
private ImporterBootstrap spacesImporterBootstrap;
public void setSpacesImporterBootstrap(ImporterBootstrap spacesImporterBootstrap)
{
this.spacesImporterBootstrap = spacesImporterBootstrap;
}
@Override
protected String applyInternal() throws Exception
{
reindex("TYPE:\"wca:webform\"", spacesImporterBootstrap.getStoreRef());
return I18NUtil.getMessage(MSG_SUCCESS);
}
}

View File

@@ -26,74 +26,29 @@
package org.alfresco.repo.admin.patch.impl; package org.alfresco.repo.admin.patch.impl;
import org.alfresco.i18n.I18NUtil; import org.alfresco.i18n.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap; import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.search.Indexer;
import org.alfresco.repo.search.IndexerAndSearcher;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
/** /**
* Patch wca:webfolder objects so that the avmstore property is in the * Patch wca:webfolder objects so that the avmstore property is in the
* index in untokenized form. * index in untokenized form.
* *
* @author gavinc * @author gavinc
*
*/ */
public class AVMStorePropertyTokenisationPatch extends AbstractPatch public class AVMStorePropertyTokenisationPatch extends BaseReindexingPatch
{ {
private static final String MSG_SUCCESS = "patch.avmStoreAsIdentifier.result"; private static final String MSG_SUCCESS = "patch.avmStoreAsIdentifier.result";
private ImporterBootstrap spacesImporterBootstrap; private ImporterBootstrap spacesImporterBootstrap;
private IndexerAndSearcher indexerAndSearcher;
public AVMStorePropertyTokenisationPatch()
{
}
public void setSpacesImporterBootstrap(ImporterBootstrap spacesImporterBootstrap) public void setSpacesImporterBootstrap(ImporterBootstrap spacesImporterBootstrap)
{ {
this.spacesImporterBootstrap = spacesImporterBootstrap; this.spacesImporterBootstrap = spacesImporterBootstrap;
} }
public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher)
{
this.indexerAndSearcher = indexerAndSearcher;
}
@Override @Override
protected String applyInternal() throws Exception protected String applyInternal() throws Exception
{ {
reindex("TYPE:\"wca:webfolder\"", spacesImporterBootstrap.getStoreRef()); reindex("TYPE:\"wca:webfolder\"", spacesImporterBootstrap.getStoreRef());
return I18NUtil.getMessage(MSG_SUCCESS); return I18NUtil.getMessage(MSG_SUCCESS);
} }
private void reindex(String query, StoreRef store)
{
SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(query);
sp.addStore(store);
ResultSet rs = null;
try
{
rs = searchService.query(sp);
for(ResultSetRow row : rs)
{
Indexer indexer = indexerAndSearcher.getIndexer(row.getNodeRef().getStoreRef());
indexer.updateNode(row.getNodeRef());
}
}
finally
{
if(rs != null)
{
rs.close();
}
}
}
} }

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.admin.patch.impl;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.search.Indexer;
import org.alfresco.repo.search.IndexerAndSearcher;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
/**
* Base patch for reindexing nodes in a store based on a lucene query
*
* @author Kevin Roast
* @author gavinc
*/
public abstract class BaseReindexingPatch extends AbstractPatch
{
protected IndexerAndSearcher indexerAndSearcher;
public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher)
{
this.indexerAndSearcher = indexerAndSearcher;
}
/**
* Reindex a collection of nodes in a store based on a Lucene query
*
* @param query The Lucene query to execute to return nodes
* @param store The Store containing the nodes to reindex
*/
protected void reindex(String query, StoreRef store)
{
SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(query);
sp.addStore(store);
ResultSet rs = null;
try
{
rs = searchService.query(sp);
for(ResultSetRow row : rs)
{
Indexer indexer = indexerAndSearcher.getIndexer(row.getNodeRef().getStoreRef());
indexer.updateNode(row.getNodeRef());
}
}
finally
{
if (rs != null)
{
rs.close();
}
}
}
}

View File

@@ -15,11 +15,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" * http://www.alfresco.com/legal/licensing"
*/ */
@@ -44,6 +44,7 @@ import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.avm.util.SimplePath; import org.alfresco.repo.avm.util.SimplePath;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.remote.AVMRemoteImpl; import org.alfresco.repo.remote.AVMRemoteImpl;
import org.alfresco.repo.remote.AVMSyncServiceRemote;
import org.alfresco.repo.remote.ClientTicketHolder; import org.alfresco.repo.remote.ClientTicketHolder;
import org.alfresco.repo.remote.ClientTicketHolderThread; import org.alfresco.repo.remote.ClientTicketHolderThread;
import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ActionService;
@@ -62,6 +63,7 @@ import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncService; import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.remote.AVMRemote; import org.alfresco.service.cmr.remote.AVMRemote;
import org.alfresco.service.cmr.remote.AVMRemoteTransport; import org.alfresco.service.cmr.remote.AVMRemoteTransport;
import org.alfresco.service.cmr.remote.AVMSyncServiceTransport;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -79,7 +81,7 @@ public class DeploymentServiceImpl implements DeploymentService
* The local AVMService Instance. * The local AVMService Instance.
*/ */
private AVMService fAVMService; private AVMService fAVMService;
/** /**
* The Ticket holder. * The Ticket holder.
*/ */
@@ -92,7 +94,7 @@ public class DeploymentServiceImpl implements DeploymentService
{ {
fTicketHolder = new ClientTicketHolderThread(); fTicketHolder = new ClientTicketHolderThread();
} }
/** /**
* Setter. * Setter.
* @param service The instance to set. * @param service The instance to set.
@@ -101,7 +103,7 @@ public class DeploymentServiceImpl implements DeploymentService
{ {
fAVMService = service; fAVMService = service;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.deploy.DeploymentService#deployDifference(int, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean) * @see org.alfresco.service.cmr.avm.deploy.DeploymentService#deployDifference(int, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean)
*/ */
@@ -113,7 +115,7 @@ public class DeploymentServiceImpl implements DeploymentService
AVMRemote remote = getRemote(hostName, port, userName, password); AVMRemote remote = getRemote(hostName, port, userName, password);
if (callback != null) if (callback != null)
{ {
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.START, DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.START,
new Pair<Integer, String>(version, srcPath), new Pair<Integer, String>(version, srcPath),
dstPath); dstPath);
callback.eventOccurred(event); callback.eventOccurred(event);
@@ -153,14 +155,14 @@ public class DeploymentServiceImpl implements DeploymentService
throw new AVMNotFoundException("Node Not Found: " + parentBase[0]); throw new AVMNotFoundException("Node Not Found: " + parentBase[0]);
} }
} }
snapshot = remote.createSnapshot(storePath[0], "PreDeploy", "Pre Deployment Snapshot").get(storePath[0]); snapshot = remote.createSnapshot(storePath[0], "PreDeploy", "Pre Deployment Snapshot").get(storePath[0]);
} }
// Get the root of the deployment on the destination server. // Get the root of the deployment on the destination server.
AVMNodeDescriptor dstRoot = remote.lookup(-1, dstPath); AVMNodeDescriptor dstRoot = remote.lookup(-1, dstPath);
if (dstRoot == null) if (dstRoot == null)
{ {
// If it doesn't exist, do a copyDirectory to create it. // If it doesn't exist, do a copyDirectory to create it.
DeploymentEvent event = DeploymentEvent event =
new DeploymentEvent(DeploymentEvent.Type.COPIED, new DeploymentEvent(DeploymentEvent.Type.COPIED,
new Pair<Integer, String>(version, srcPath), new Pair<Integer, String>(version, srcPath),
dstPath); dstPath);
@@ -177,7 +179,7 @@ public class DeploymentServiceImpl implements DeploymentService
remote.createSnapshot(storePath[0], "Deployment", "Post Deployment Snapshot."); remote.createSnapshot(storePath[0], "Deployment", "Post Deployment Snapshot.");
if (callback != null) if (callback != null)
{ {
event = new DeploymentEvent(DeploymentEvent.Type.END, event = new DeploymentEvent(DeploymentEvent.Type.END,
new Pair<Integer, String>(version, srcPath), new Pair<Integer, String>(version, srcPath),
dstPath); dstPath);
callback.eventOccurred(event); callback.eventOccurred(event);
@@ -187,7 +189,7 @@ public class DeploymentServiceImpl implements DeploymentService
if (!dstRoot.isDirectory()) if (!dstRoot.isDirectory())
{ {
throw new AVMWrongTypeException("Not a Directory: " + dstPath); throw new AVMWrongTypeException("Not a Directory: " + dstPath);
} }
// The corresponding directory exists so recursively deploy. // The corresponding directory exists so recursively deploy.
try try
{ {
@@ -195,7 +197,7 @@ public class DeploymentServiceImpl implements DeploymentService
remote.createSnapshot(storePath[0], "Deployment", "Post Deployment Snapshot."); remote.createSnapshot(storePath[0], "Deployment", "Post Deployment Snapshot.");
if (callback != null) if (callback != null)
{ {
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.END, DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.END,
new Pair<Integer, String>(version, srcPath), new Pair<Integer, String>(version, srcPath),
dstPath); dstPath);
callback.eventOccurred(event); callback.eventOccurred(event);
@@ -223,9 +225,9 @@ public class DeploymentServiceImpl implements DeploymentService
finally finally
{ {
fTicketHolder.setTicket(null); fTicketHolder.setTicket(null);
} }
} }
/** /**
* Deploy all the children of corresponding directories. * Deploy all the children of corresponding directories.
* @param src The source directory. * @param src The source directory.
@@ -234,9 +236,9 @@ public class DeploymentServiceImpl implements DeploymentService
* @param dontDelete Flag for not deleting. * @param dontDelete Flag for not deleting.
* @param dontDo Flag for dry run. * @param dontDo Flag for dry run.
*/ */
private void deployDirectoryPush(int version, private void deployDirectoryPush(int version,
AVMNodeDescriptor src, AVMNodeDescriptor dst, AVMNodeDescriptor src, AVMNodeDescriptor dst,
AVMRemote remote, AVMRemote remote,
NameMatcher matcher, NameMatcher matcher,
boolean dontDelete, boolean dontDo, boolean dontDelete, boolean dontDo,
DeploymentReport report, DeploymentReport report,
@@ -278,7 +280,7 @@ public class DeploymentServiceImpl implements DeploymentService
String destination = AVMNodeConverter.ExtendAVMPath(dst.getPath(), name); String destination = AVMNodeConverter.ExtendAVMPath(dst.getPath(), name);
if (!excluded(matcher, null, destination)) if (!excluded(matcher, null, destination))
{ {
DeploymentEvent event = DeploymentEvent event =
new DeploymentEvent(DeploymentEvent.Type.DELETED, new DeploymentEvent(DeploymentEvent.Type.DELETED,
source, source,
destination); destination);
@@ -296,7 +298,7 @@ public class DeploymentServiceImpl implements DeploymentService
} }
} }
} }
/** /**
* Push out a single node. * Push out a single node.
* @param src The source node. * @param src The source node.
@@ -308,7 +310,7 @@ public class DeploymentServiceImpl implements DeploymentService
*/ */
private void deploySinglePush(int version, private void deploySinglePush(int version,
AVMNodeDescriptor src, AVMNodeDescriptor dstParent, AVMNodeDescriptor src, AVMNodeDescriptor dstParent,
AVMNodeDescriptor dst, AVMRemote remote, AVMNodeDescriptor dst, AVMRemote remote,
NameMatcher matcher, NameMatcher matcher,
boolean dontDelete, boolean dontDo, boolean dontDelete, boolean dontDo,
DeploymentReport report, DeploymentReport report,
@@ -338,7 +340,7 @@ public class DeploymentServiceImpl implements DeploymentService
copyDirectory(version, src, dstParent, remote, matcher); copyDirectory(version, src, dstParent, remote, matcher);
return; return;
} }
Pair<Integer, String> source = Pair<Integer, String> source =
new Pair<Integer, String>(version, src.getPath()); new Pair<Integer, String>(version, src.getPath());
String destination = AVMNodeConverter.ExtendAVMPath(dstParent.getPath(), src.getName()); String destination = AVMNodeConverter.ExtendAVMPath(dstParent.getPath(), src.getName());
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED, DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED,
@@ -369,7 +371,7 @@ public class DeploymentServiceImpl implements DeploymentService
deployDirectoryPush(version, src, dst, remote, matcher, dontDelete, dontDo, report, callback); deployDirectoryPush(version, src, dst, remote, matcher, dontDelete, dontDo, report, callback);
return; return;
} }
Pair<Integer, String> source = Pair<Integer, String> source =
new Pair<Integer, String>(version, src.getPath()); new Pair<Integer, String>(version, src.getPath());
String destination = dst.getPath(); String destination = dst.getPath();
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED, DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED,
@@ -395,7 +397,7 @@ public class DeploymentServiceImpl implements DeploymentService
{ {
return; return;
} }
Pair<Integer, String> source = Pair<Integer, String> source =
new Pair<Integer, String>(version, src.getPath()); new Pair<Integer, String>(version, src.getPath());
String destination = dst.getPath(); String destination = dst.getPath();
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.UPDATED, DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.UPDATED,
@@ -439,7 +441,7 @@ public class DeploymentServiceImpl implements DeploymentService
copyStream(in, out); copyStream(in, out);
copyMetadata(version, src, remote.lookup(-1, dstParent.getPath() + '/' + dst.getName()), remote); copyMetadata(version, src, remote.lookup(-1, dstParent.getPath() + '/' + dst.getName()), remote);
} }
/** /**
* Recursively copy a directory. * Recursively copy a directory.
* @param src * @param src
@@ -453,7 +455,7 @@ public class DeploymentServiceImpl implements DeploymentService
remote.createDirectory(parent.getPath(), src.getName()); remote.createDirectory(parent.getPath(), src.getName());
AVMNodeDescriptor newParent = remote.lookup(-1, parent.getPath() + '/' + src.getName()); AVMNodeDescriptor newParent = remote.lookup(-1, parent.getPath() + '/' + src.getName());
copyMetadata(version, src, newParent, remote); copyMetadata(version, src, newParent, remote);
SortedMap<String, AVMNodeDescriptor> list = SortedMap<String, AVMNodeDescriptor> list =
fAVMService.getDirectoryListing(src); fAVMService.getDirectoryListing(src);
// For each child in the source directory. // For each child in the source directory.
for (AVMNodeDescriptor child : list.values()) for (AVMNodeDescriptor child : list.values())
@@ -474,7 +476,7 @@ public class DeploymentServiceImpl implements DeploymentService
} }
} }
} }
/** /**
* Utility for copying from one stream to another. * Utility for copying from one stream to another.
* @param in The input stream. * @param in The input stream.
@@ -488,7 +490,7 @@ public class DeploymentServiceImpl implements DeploymentService
{ {
while ((read = in.read(buff)) != -1) while ((read = in.read(buff)) != -1)
{ {
out.write(buff, 0, read); out.write(buff, 0, read);
} }
in.close(); in.close();
out.close(); out.close();
@@ -520,7 +522,7 @@ public class DeploymentServiceImpl implements DeploymentService
remote.setMimeType(dst.getPath(), contData.getMimetype()); remote.setMimeType(dst.getPath(), contData.getMimetype());
} }
} }
/** /**
* Utility to get an AVMRemote from a remote Alfresco Server. * Utility to get an AVMRemote from a remote Alfresco Server.
* @param hostName * @param hostName
@@ -558,7 +560,7 @@ public class DeploymentServiceImpl implements DeploymentService
throw new AVMException("Could not Initialize Remote Connection to " + hostName, e); throw new AVMException("Could not Initialize Remote Connection to " + hostName, e);
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.deploy.DeploymentService#getRemoteActionService(java.lang.String, int, java.lang.String, java.lang.String) * @see org.alfresco.service.cmr.avm.deploy.DeploymentService#getRemoteActionService(java.lang.String, int, java.lang.String, java.lang.String)
*/ */
@@ -624,18 +626,21 @@ public class DeploymentServiceImpl implements DeploymentService
{ {
RmiProxyFactoryBean syncFactory = new RmiProxyFactoryBean(); RmiProxyFactoryBean syncFactory = new RmiProxyFactoryBean();
syncFactory.setRefreshStubOnConnectFailure(true); syncFactory.setRefreshStubOnConnectFailure(true);
syncFactory.setServiceInterface(AVMSyncService.class); syncFactory.setServiceInterface(AVMSyncServiceTransport.class);
syncFactory.setServiceUrl("rmi://" + hostName + ":" + port + "/avmsync"); syncFactory.setServiceUrl("rmi://" + hostName + ":" + port + "/avmsync");
syncFactory.afterPropertiesSet(); syncFactory.afterPropertiesSet();
AVMSyncService syncService = (AVMSyncService)syncFactory.getObject(); AVMSyncServiceTransport syncServiceTransport = (AVMSyncServiceTransport)syncFactory.getObject();
return syncService; AVMSyncServiceRemote remote = new AVMSyncServiceRemote();
remote.setAvmSyncServiceTransport(syncServiceTransport);
remote.setClientTicketHolder(fTicketHolder);
return remote;
} }
catch (Exception e) catch (Exception e)
{ {
throw new AVMException("Could not roll back failed deployment to " + hostName, e); throw new AVMException("Could not roll back failed deployment to " + hostName, e);
} }
} }
/** /**
* Helper function to create a non existent destination. * Helper function to create a non existent destination.
* @param remote The AVMRemote instance. * @param remote The AVMRemote instance.
@@ -668,7 +673,7 @@ public class DeploymentServiceImpl implements DeploymentService
prevPath = currPath; prevPath = currPath;
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.deploy.DeploymentService#deployDifferenceFS(int, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean) * @see org.alfresco.service.cmr.avm.deploy.DeploymentService#deployDifferenceFS(int, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean)
*/ */
@@ -703,7 +708,7 @@ public class DeploymentServiceImpl implements DeploymentService
report.add(event); report.add(event);
return report; return report;
} }
private void deployDirectoryPush(DeploymentReceiverService service, String ticket, private void deployDirectoryPush(DeploymentReceiverService service, String ticket,
DeploymentReport report, DeploymentCallback callback, DeploymentReport report, DeploymentCallback callback,
int version, int version,
@@ -738,7 +743,7 @@ public class DeploymentServiceImpl implements DeploymentService
if (!excluded(matcher, null, newDstPath)) if (!excluded(matcher, null, newDstPath))
{ {
service.delete(ticket, newDstPath); service.delete(ticket, newDstPath);
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.DELETED, DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.DELETED,
new Pair<Integer, String>(version, extendPath(srcPath, dst.getName())), new Pair<Integer, String>(version, extendPath(srcPath, dst.getName())),
newDstPath); newDstPath);
if (callback != null) if (callback != null)
@@ -821,7 +826,7 @@ public class DeploymentServiceImpl implements DeploymentService
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.DELETED, DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.DELETED,
new Pair<Integer, String>(version, extendPath(srcPath, dst.getName())), new Pair<Integer, String>(version, extendPath(srcPath, dst.getName())),
newDstPath); newDstPath);
if (callback != null) if (callback != null)
{ {
callback.eventOccurred(event); callback.eventOccurred(event);
} }
@@ -829,7 +834,7 @@ public class DeploymentServiceImpl implements DeploymentService
dst = null; dst = null;
} }
} }
/** /**
* Copy or overwrite a single file. * Copy or overwrite a single file.
* @param service * @param service
@@ -840,7 +845,7 @@ public class DeploymentServiceImpl implements DeploymentService
* @param src * @param src
* @param dstPath * @param dstPath
*/ */
private void copyFile(DeploymentReceiverService service, String ticket, private void copyFile(DeploymentReceiverService service, String ticket,
DeploymentReport report, DeploymentCallback callback, int version, DeploymentReport report, DeploymentCallback callback, int version,
AVMNodeDescriptor src, String dstPath) AVMNodeDescriptor src, String dstPath)
{ {
@@ -865,7 +870,7 @@ public class DeploymentServiceImpl implements DeploymentService
throw new AVMException("Failed to copy " + src + ". Deployment aborted.", e); throw new AVMException("Failed to copy " + src + ". Deployment aborted.", e);
} }
} }
/** /**
* Copy a file or directory to an empty destination. * Copy a file or directory to an empty destination.
* @param service * @param service
@@ -877,7 +882,7 @@ public class DeploymentServiceImpl implements DeploymentService
* @param parentPath * @param parentPath
*/ */
private void copy(DeploymentReceiverService service, String ticket, private void copy(DeploymentReceiverService service, String ticket,
DeploymentReport report, DeploymentCallback callback, DeploymentReport report, DeploymentCallback callback,
int version, AVMNodeDescriptor src, String parentPath, NameMatcher matcher) int version, AVMNodeDescriptor src, String parentPath, NameMatcher matcher)
{ {
String dstPath = extendPath(parentPath, src.getName()); String dstPath = extendPath(parentPath, src.getName());
@@ -905,7 +910,7 @@ public class DeploymentServiceImpl implements DeploymentService
} }
} }
} }
/** /**
* Extend a path. * Extend a path.
* @param path * @param path
@@ -920,7 +925,7 @@ public class DeploymentServiceImpl implements DeploymentService
} }
return path + '/' + name; return path + '/' + name;
} }
/** /**
* Returns true if either srcPath or dstPath are matched by matcher. * Returns true if either srcPath or dstPath are matched by matcher.
* @param matcher * @param matcher

View File

@@ -401,7 +401,7 @@ public final class QName implements QNamePattern, Serializable, Cloneable
{ {
QName qname = null; QName qname = null;
if (str == null && str.length() == 0) if (str == null || str.length() == 0)
{ {
throw new IllegalArgumentException("str parameter is mandatory"); throw new IllegalArgumentException("str parameter is mandatory");
} }
@@ -449,7 +449,7 @@ public final class QName implements QNamePattern, Serializable, Cloneable
{ {
String result = str; String result = str;
if (str == null && str.length() == 0) if (str == null || str.length() == 0)
{ {
throw new IllegalArgumentException("str parameter is mandatory"); throw new IllegalArgumentException("str parameter is mandatory");
} }