mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
. Merge horrors fixed
. Code compile issue fixed git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4669 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -333,10 +333,10 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
|
|||||||
Map<String, Object> model = new HashMap<String, Object>(8, 1.0f);
|
Map<String, Object> model = new HashMap<String, Object>(8, 1.0f);
|
||||||
|
|
||||||
NodeRef person = personService.getPerson(authService.getCurrentUserName());
|
NodeRef person = personService.getPerson(authService.getCurrentUserName());
|
||||||
model.put("person", new TemplateNode(person, serviceRegistry));
|
model.put("person", new TemplateNode(person, serviceRegistry, null));
|
||||||
model.put("document", new TemplateNode(ref, serviceRegistry));
|
model.put("document", new TemplateNode(ref, serviceRegistry, null));
|
||||||
NodeRef parent = serviceRegistry.getNodeService().getPrimaryParent(ref).getParentRef();
|
NodeRef parent = serviceRegistry.getNodeService().getPrimaryParent(ref).getParentRef();
|
||||||
model.put("space", new TemplateNode(parent, serviceRegistry));
|
model.put("space", new TemplateNode(parent, serviceRegistry, null));
|
||||||
|
|
||||||
// current date/time is useful to have and isn't supplied by FreeMarker by default
|
// current date/time is useful to have and isn't supplied by FreeMarker by default
|
||||||
model.put("date", new Date());
|
model.put("date", new Date());
|
||||||
|
@@ -68,7 +68,7 @@ public final class AVM extends BaseScriptImplementation implements Scopeable
|
|||||||
AVMNodeDescriptor nodeDesc = this.services.getAVMService().lookup(-1, rootPath);
|
AVMNodeDescriptor nodeDesc = this.services.getAVMService().lookup(-1, rootPath);
|
||||||
if (nodeDesc != null)
|
if (nodeDesc != null)
|
||||||
{
|
{
|
||||||
rootNode = new AVMNode(AVMNodeConverter.ToNodeRef(-1, rootPath), this.services, null, this.scope);
|
rootNode = new AVMNode(AVMNodeConverter.ToNodeRef(-1, rootPath), this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rootNode;
|
return rootNode;
|
||||||
@@ -89,7 +89,7 @@ public final class AVM extends BaseScriptImplementation implements Scopeable
|
|||||||
AVMNodeDescriptor nodeDesc = this.services.getAVMService().lookup(-1, path);
|
AVMNodeDescriptor nodeDesc = this.services.getAVMService().lookup(-1, path);
|
||||||
if (nodeDesc != null)
|
if (nodeDesc != null)
|
||||||
{
|
{
|
||||||
node = new AVMNode(AVMNodeConverter.ToNodeRef(-1, path), this.services, null, this.scope);
|
node = new AVMNode(AVMNodeConverter.ToNodeRef(-1, path), this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
|
@@ -39,9 +39,9 @@ public class AVMNode extends Node
|
|||||||
* @param services
|
* @param services
|
||||||
* @param resolver
|
* @param resolver
|
||||||
*/
|
*/
|
||||||
public AVMNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver)
|
public AVMNode(NodeRef nodeRef, ServiceRegistry services)
|
||||||
{
|
{
|
||||||
super(nodeRef, services, resolver);
|
super(nodeRef, services);
|
||||||
this.path = AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond();
|
this.path = AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,9 +53,9 @@ public class AVMNode extends Node
|
|||||||
* @param resolver
|
* @param resolver
|
||||||
* @param scope
|
* @param scope
|
||||||
*/
|
*/
|
||||||
public AVMNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver, Scriptable scope)
|
public AVMNode(NodeRef nodeRef, ServiceRegistry services, Scriptable scope)
|
||||||
{
|
{
|
||||||
super(nodeRef, services, resolver, scope);
|
super(nodeRef, services, scope);
|
||||||
this.path = AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond();
|
this.path = AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,9 +63,9 @@ public class AVMNode extends Node
|
|||||||
* Factory method
|
* Factory method
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Node newInstance(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver, Scriptable scope)
|
public Node newInstance(NodeRef nodeRef, ServiceRegistry services, Scriptable scope)
|
||||||
{
|
{
|
||||||
return new AVMNode(nodeRef, services, resolver, scope);
|
return new AVMNode(nodeRef, services, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: changing the 'name' property (either directly using .name or with .properties.name)
|
// TODO: changing the 'name' property (either directly using .name or with .properties.name)
|
||||||
@@ -121,7 +121,7 @@ public class AVMNode extends Node
|
|||||||
this.services.getAVMService().copy(-1, getPath(), destination, getName());
|
this.services.getAVMService().copy(-1, getPath(), destination, getName());
|
||||||
copy = newInstance(
|
copy = newInstance(
|
||||||
AVMNodeConverter.ToNodeRef(-1, destination + '/' + getName()),
|
AVMNodeConverter.ToNodeRef(-1, destination + '/' + getName()),
|
||||||
this.services, null, this.scope);
|
this.services, this.scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
|
@@ -25,6 +25,7 @@ import org.alfresco.model.ContentModel;
|
|||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||||
import org.alfresco.service.cmr.repository.TemplateNode;
|
import org.alfresco.service.cmr.repository.TemplateNode;
|
||||||
import org.alfresco.service.cmr.search.CategoryService;
|
import org.alfresco.service.cmr.search.CategoryService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
@@ -34,8 +35,6 @@ import org.alfresco.service.namespace.QName;
|
|||||||
*/
|
*/
|
||||||
public class CategoryTemplateNode extends TemplateNode
|
public class CategoryTemplateNode extends TemplateNode
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = -2595282439089450151L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@@ -43,9 +42,9 @@ public class CategoryTemplateNode extends TemplateNode
|
|||||||
* @param services
|
* @param services
|
||||||
* @param resolver
|
* @param resolver
|
||||||
*/
|
*/
|
||||||
public CategoryTemplateNode(NodeRef nodeRef, ServiceRegistry services)
|
public CategoryTemplateNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver)
|
||||||
{
|
{
|
||||||
super(nodeRef, services);
|
super(nodeRef, services, resolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -164,7 +163,7 @@ public class CategoryTemplateNode extends TemplateNode
|
|||||||
for (ChildAssociationRef ref : childRefs)
|
for (ChildAssociationRef ref : childRefs)
|
||||||
{
|
{
|
||||||
// create our Node representation from the NodeRef
|
// create our Node representation from the NodeRef
|
||||||
TemplateNode child = new TemplateNode(ref.getChildRef(), this.services);
|
TemplateNode child = new TemplateNode(ref.getChildRef(), this.services, this.imageResolver);
|
||||||
answer.add(child);
|
answer.add(child);
|
||||||
}
|
}
|
||||||
return answer;
|
return answer;
|
||||||
@@ -176,7 +175,7 @@ public class CategoryTemplateNode extends TemplateNode
|
|||||||
for (ChildAssociationRef ref : childRefs)
|
for (ChildAssociationRef ref : childRefs)
|
||||||
{
|
{
|
||||||
// create our Node representation from the NodeRef
|
// create our Node representation from the NodeRef
|
||||||
CategoryTemplateNode child = new CategoryTemplateNode(ref.getChildRef(), this.services);
|
CategoryTemplateNode child = new CategoryTemplateNode(ref.getChildRef(), this.services, this.imageResolver);
|
||||||
answer.add(child);
|
answer.add(child);
|
||||||
}
|
}
|
||||||
return answer;
|
return answer;
|
||||||
@@ -185,16 +184,17 @@ public class CategoryTemplateNode extends TemplateNode
|
|||||||
private List<TemplateNode> buildMixedNodeList(Collection<ChildAssociationRef> cars)
|
private List<TemplateNode> buildMixedNodeList(Collection<ChildAssociationRef> cars)
|
||||||
{
|
{
|
||||||
List<TemplateNode> nodes = new ArrayList<TemplateNode>(cars.size());
|
List<TemplateNode> nodes = new ArrayList<TemplateNode>(cars.size());
|
||||||
|
int i = 0;
|
||||||
for (ChildAssociationRef car : cars)
|
for (ChildAssociationRef car : cars)
|
||||||
{
|
{
|
||||||
QName type = services.getNodeService().getType(car.getChildRef());
|
QName type = services.getNodeService().getType(car.getChildRef());
|
||||||
if (services.getDictionaryService().isSubClass(type, ContentModel.TYPE_CATEGORY))
|
if (services.getDictionaryService().isSubClass(type, ContentModel.TYPE_CATEGORY))
|
||||||
{
|
{
|
||||||
nodes.add(new CategoryTemplateNode(car.getChildRef(), this.services));
|
nodes.add(new CategoryTemplateNode(car.getChildRef(), this.services, this.imageResolver));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nodes.add(new TemplateNode(car.getChildRef(), this.services));
|
nodes.add(new TemplateNode(car.getChildRef(), this.services, this.imageResolver));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nodes;
|
return nodes;
|
||||||
|
@@ -49,6 +49,7 @@ import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
|||||||
import org.alfresco.service.cmr.repository.NoTransformerException;
|
import org.alfresco.service.cmr.repository.NoTransformerException;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||||
import org.alfresco.service.cmr.repository.TemplateNode;
|
import org.alfresco.service.cmr.repository.TemplateNode;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
@@ -76,9 +77,6 @@ import org.springframework.util.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class Node implements Serializable, Scopeable
|
public class Node implements Serializable, Scopeable
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Comment for <code>serialVersionUID</code>
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = -3378946227712939600L;
|
private static final long serialVersionUID = -3378946227712939600L;
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(Node.class);
|
private static Log logger = LogFactory.getLog(Node.class);
|
||||||
@@ -86,9 +84,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
private final static String NAMESPACE_BEGIN = "" + QName.NAMESPACE_BEGIN;
|
private final static String NAMESPACE_BEGIN = "" + QName.NAMESPACE_BEGIN;
|
||||||
|
|
||||||
private final static String CONTENT_DEFAULT_URL = "/download/direct/{0}/{1}/{2}/{3}";
|
private final static String CONTENT_DEFAULT_URL = "/download/direct/{0}/{1}/{2}/{3}";
|
||||||
|
|
||||||
private final static String CONTENT_PROP_URL = "/download/direct/{0}/{1}/{2}/{3}?property={4}";
|
private final static String CONTENT_PROP_URL = "/download/direct/{0}/{1}/{2}/{3}?property={4}";
|
||||||
|
|
||||||
private final static String FOLDER_BROWSE_URL = "/navigate/browse/{0}/{1}/{2}";
|
private final static String FOLDER_BROWSE_URL = "/navigate/browse/{0}/{1}/{2}";
|
||||||
|
|
||||||
/** Root scope for this object */
|
/** Root scope for this object */
|
||||||
@@ -99,9 +95,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
|
|
||||||
/** Cached values */
|
/** Cached values */
|
||||||
protected NodeRef nodeRef;
|
protected NodeRef nodeRef;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private QName type;
|
private QName type;
|
||||||
protected String id;
|
protected String id;
|
||||||
|
|
||||||
@@ -118,20 +112,13 @@ public class Node implements Serializable, Scopeable
|
|||||||
private ScriptableQNameMap<String, Serializable> properties = null;
|
private ScriptableQNameMap<String, Serializable> properties = null;
|
||||||
|
|
||||||
protected ServiceRegistry services = null;
|
protected ServiceRegistry services = null;
|
||||||
|
|
||||||
private NodeService nodeService = null;
|
private NodeService nodeService = null;
|
||||||
|
|
||||||
private Boolean isDocument = null;
|
private Boolean isDocument = null;
|
||||||
|
|
||||||
private Boolean isContainer = null;
|
private Boolean isContainer = null;
|
||||||
|
|
||||||
private String displayPath = null;
|
private String displayPath = null;
|
||||||
|
|
||||||
protected TemplateImageResolver imageResolver = null;
|
protected TemplateImageResolver imageResolver = null;
|
||||||
protected Node parent = null;
|
protected Node parent = null;
|
||||||
|
|
||||||
private ChildAssociationRef primaryParentAssoc = null;
|
private ChildAssociationRef primaryParentAssoc = null;
|
||||||
|
|
||||||
// NOTE: see the reset() method when adding new cached members!
|
// NOTE: see the reset() method when adding new cached members!
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
@@ -140,12 +127,9 @@ public class Node implements Serializable, Scopeable
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param nodeRef
|
* @param nodeRef The NodeRef this Node wrapper represents
|
||||||
* The NodeRef this Node wrapper represents
|
* @param services The ServiceRegistry the Node can use to access services
|
||||||
* @param services
|
* @param resolver Image resolver to use to retrieve icons
|
||||||
* The ServiceRegistry the Node can use to access services
|
|
||||||
* @param resolver
|
|
||||||
* Image resolver to use to retrieve icons
|
|
||||||
*/
|
*/
|
||||||
public Node(NodeRef nodeRef, ServiceRegistry services)
|
public Node(NodeRef nodeRef, ServiceRegistry services)
|
||||||
{
|
{
|
||||||
@@ -155,14 +139,10 @@ public class Node implements Serializable, Scopeable
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param nodeRef
|
* @param nodeRef The NodeRef this Node wrapper represents
|
||||||
* The NodeRef this Node wrapper represents
|
* @param services The ServiceRegistry the Node can use to access services
|
||||||
* @param services
|
* @param resolver Image resolver to use to retrieve icons
|
||||||
* The ServiceRegistry the Node can use to access services
|
* @param scope Root scope for this Node
|
||||||
* @param resolver
|
|
||||||
* Image resolver to use to retrieve icons
|
|
||||||
* @param scope
|
|
||||||
* Root scope for this Node
|
|
||||||
*/
|
*/
|
||||||
public Node(NodeRef nodeRef, ServiceRegistry services, Scriptable scope)
|
public Node(NodeRef nodeRef, ServiceRegistry services, Scriptable scope)
|
||||||
{
|
{
|
||||||
@@ -195,29 +175,24 @@ public class Node implements Serializable, Scopeable
|
|||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj) return true;
|
||||||
return true;
|
if (obj == null) return false;
|
||||||
if (obj == null)
|
if (getClass() != obj.getClass()) return false;
|
||||||
return false;
|
|
||||||
if (getClass() != obj.getClass())
|
|
||||||
return false;
|
|
||||||
final Node other = (Node) obj;
|
final Node other = (Node) obj;
|
||||||
if (nodeRef == null)
|
if (nodeRef == null)
|
||||||
{
|
{
|
||||||
if (other.nodeRef != null)
|
if (other.nodeRef != null) return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else if (!nodeRef.equals(other.nodeRef))
|
else if (!nodeRef.equals(other.nodeRef)) return false;
|
||||||
return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory method
|
* Factory method
|
||||||
*/
|
*/
|
||||||
public Node newInstance(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver, Scriptable scope)
|
public Node newInstance(NodeRef nodeRef, ServiceRegistry services, Scriptable scope)
|
||||||
{
|
{
|
||||||
return new Node(nodeRef, services, resolver, scope);
|
return new Node(nodeRef, services, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -339,8 +314,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
for (int i = 0; i < childRefs.size(); i++)
|
for (int i = 0; i < childRefs.size(); i++)
|
||||||
{
|
{
|
||||||
// create our Node representation from the NodeRef
|
// create our Node representation from the NodeRef
|
||||||
Node child = newInstance(
|
Node child = newInstance(childRefs.get(i).getChildRef(), this.services, this.scope);
|
||||||
childRefs.get(i).getChildRef(), this.services, this.imageResolver, this.scope);
|
|
||||||
this.children[i] = child;
|
this.children[i] = child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -426,8 +400,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
System.arraycopy(nodes, 0, newNodes, 0, nodes.length);
|
System.arraycopy(nodes, 0, newNodes, 0, nodes.length);
|
||||||
nodes = newNodes;
|
nodes = newNodes;
|
||||||
}
|
}
|
||||||
nodes[nodes.length - 1] = newInstance(
|
nodes[nodes.length - 1] = newInstance(ref.getTargetRef(), this.services, this.scope);
|
||||||
ref.getTargetRef(), this.services, this.imageResolver, this.scope);
|
|
||||||
|
|
||||||
this.assocs.put(ref.getTypeQName().toString(), nodes);
|
this.assocs.put(ref.getTypeQName().toString(), nodes);
|
||||||
}
|
}
|
||||||
@@ -670,7 +643,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
// handle root node (no parent!)
|
// handle root node (no parent!)
|
||||||
if (parentRef != null)
|
if (parentRef != null)
|
||||||
{
|
{
|
||||||
parent = newInstance(parentRef, this.services, this.imageResolver, this.scope);
|
parent = newInstance(parentRef, this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,8 +871,8 @@ public class Node implements Serializable, Scopeable
|
|||||||
*/
|
*/
|
||||||
public void removePermission(String permission)
|
public void removePermission(String permission)
|
||||||
{
|
{
|
||||||
this.services.getPermissionService().deletePermission(this.nodeRef, PermissionService.ALL_AUTHORITIES,
|
this.services.getPermissionService()
|
||||||
permission);
|
.deletePermission(this.nodeRef, PermissionService.ALL_AUTHORITIES, permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1029,7 +1002,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
{
|
{
|
||||||
FileInfo fileInfo = this.services.getFileFolderService().create(this.nodeRef, name,
|
FileInfo fileInfo = this.services.getFileFolderService().create(this.nodeRef, name,
|
||||||
ContentModel.TYPE_CONTENT);
|
ContentModel.TYPE_CONTENT);
|
||||||
node = newInstance(fileInfo.getNodeRef(), this.services, this.imageResolver, this.scope);
|
node = newInstance(fileInfo.getNodeRef(), this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (FileExistsException fileErr)
|
catch (FileExistsException fileErr)
|
||||||
@@ -1062,7 +1035,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
{
|
{
|
||||||
FileInfo fileInfo = this.services.getFileFolderService().create(this.nodeRef, name,
|
FileInfo fileInfo = this.services.getFileFolderService().create(this.nodeRef, name,
|
||||||
ContentModel.TYPE_FOLDER);
|
ContentModel.TYPE_FOLDER);
|
||||||
node = newInstance(fileInfo.getNodeRef(), this.services, this.imageResolver, this.scope);
|
node = newInstance(fileInfo.getNodeRef(), this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (FileExistsException fileErr)
|
catch (FileExistsException fileErr)
|
||||||
@@ -1097,10 +1070,10 @@ public class Node implements Serializable, Scopeable
|
|||||||
{
|
{
|
||||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
||||||
props.put(ContentModel.PROP_NAME, name);
|
props.put(ContentModel.PROP_NAME, name);
|
||||||
ChildAssociationRef childAssocRef = this.nodeService.createNode(this.nodeRef,
|
ChildAssociationRef childAssocRef = this.nodeService.createNode(this.nodeRef, ContentModel.ASSOC_CONTAINS,
|
||||||
ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.ALFRESCO_URI, QName
|
QName.createQName(NamespaceService.ALFRESCO_URI, QName.createValidLocalName(name)),
|
||||||
.createValidLocalName(name)), createQName(type), props);
|
createQName(type), props);
|
||||||
node = newInstance(childAssocRef.getChildRef(), this.services, this.imageResolver, this.scope);
|
node = newInstance(childAssocRef.getChildRef(), this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AccessDeniedException accessErr)
|
catch (AccessDeniedException accessErr)
|
||||||
@@ -1169,7 +1142,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
{
|
{
|
||||||
NodeRef copyRef = this.services.getCopyService().copyAndRename(this.nodeRef, destination.getNodeRef(),
|
NodeRef copyRef = this.services.getCopyService().copyAndRename(this.nodeRef, destination.getNodeRef(),
|
||||||
ContentModel.ASSOC_CONTAINS, getPrimaryParentAssoc().getQName(), deepCopy);
|
ContentModel.ASSOC_CONTAINS, getPrimaryParentAssoc().getQName(), deepCopy);
|
||||||
copy = newInstance(copyRef, this.services, this.imageResolver, this.scope);
|
copy = newInstance(copyRef, this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AccessDeniedException accessErr)
|
catch (AccessDeniedException accessErr)
|
||||||
@@ -1325,7 +1298,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
public Node checkout()
|
public Node checkout()
|
||||||
{
|
{
|
||||||
NodeRef workingCopyRef = this.services.getCheckOutCheckInService().checkout(this.nodeRef);
|
NodeRef workingCopyRef = this.services.getCheckOutCheckInService().checkout(this.nodeRef);
|
||||||
Node workingCopy = newInstance(workingCopyRef, this.services, this.imageResolver, this.scope);
|
Node workingCopy = newInstance(workingCopyRef, this.services, this.scope);
|
||||||
|
|
||||||
// reset the aspect and properties as checking out a document causes changes
|
// reset the aspect and properties as checking out a document causes changes
|
||||||
this.properties = null;
|
this.properties = null;
|
||||||
@@ -1346,7 +1319,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
ChildAssociationRef childAssocRef = this.nodeService.getPrimaryParent(destination.getNodeRef());
|
ChildAssociationRef childAssocRef = this.nodeService.getPrimaryParent(destination.getNodeRef());
|
||||||
NodeRef workingCopyRef = this.services.getCheckOutCheckInService().checkout(this.nodeRef,
|
NodeRef workingCopyRef = this.services.getCheckOutCheckInService().checkout(this.nodeRef,
|
||||||
destination.getNodeRef(), ContentModel.ASSOC_CONTAINS, childAssocRef.getQName());
|
destination.getNodeRef(), ContentModel.ASSOC_CONTAINS, childAssocRef.getQName());
|
||||||
Node workingCopy = newInstance(workingCopyRef, this.services, this.imageResolver, this.scope);
|
Node workingCopy = newInstance(workingCopyRef, this.services, this.scope);
|
||||||
|
|
||||||
// reset the aspect and properties as checking out a document causes changes
|
// reset the aspect and properties as checking out a document causes changes
|
||||||
this.properties = null;
|
this.properties = null;
|
||||||
@@ -1395,7 +1368,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
props.put(Version.PROP_DESCRIPTION, history);
|
props.put(Version.PROP_DESCRIPTION, history);
|
||||||
props.put(VersionModel.PROP_VERSION_TYPE, majorVersion ? VersionType.MAJOR : VersionType.MINOR);
|
props.put(VersionModel.PROP_VERSION_TYPE, majorVersion ? VersionType.MAJOR : VersionType.MINOR);
|
||||||
NodeRef original = this.services.getCheckOutCheckInService().checkin(this.nodeRef, props);
|
NodeRef original = this.services.getCheckOutCheckInService().checkin(this.nodeRef, props);
|
||||||
return newInstance(original, this.services, this.imageResolver, this.scope);
|
return newInstance(original, this.services, this.scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1407,7 +1380,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
public Node cancelCheckout()
|
public Node cancelCheckout()
|
||||||
{
|
{
|
||||||
NodeRef original = this.services.getCheckOutCheckInService().cancelCheckout(this.nodeRef);
|
NodeRef original = this.services.getCheckOutCheckInService().cancelCheckout(this.nodeRef);
|
||||||
return newInstance(original, this.services, this.imageResolver, this.scope);
|
return newInstance(original, this.services, this.scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
@@ -1455,7 +1428,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
contentService.transform(reader, writer);
|
contentService.transform(reader, writer);
|
||||||
transformedNode = newInstance(nodeRef, services, imageResolver, scope);
|
transformedNode = newInstance(nodeRef, services, scope);
|
||||||
}
|
}
|
||||||
catch (NoTransformerException err)
|
catch (NoTransformerException err)
|
||||||
{
|
{
|
||||||
@@ -1494,13 +1467,10 @@ public class Node implements Serializable, Scopeable
|
|||||||
// Copy the content node to a new node
|
// Copy the content node to a new node
|
||||||
String copyName = TransformActionExecuter.transformName(this.services.getMimetypeService(), getName(),
|
String copyName = TransformActionExecuter.transformName(this.services.getMimetypeService(), getName(),
|
||||||
mimetype);
|
mimetype);
|
||||||
NodeRef copyNodeRef = this.services.getCopyService().copy(
|
NodeRef copyNodeRef = this.services.getCopyService().copy(this.nodeRef, destination,
|
||||||
this.nodeRef,
|
|
||||||
destination,
|
|
||||||
ContentModel.ASSOC_CONTAINS,
|
ContentModel.ASSOC_CONTAINS,
|
||||||
QName
|
QName.createQName(ContentModel.PROP_CONTENT.getNamespaceURI(), QName.createValidLocalName(copyName)),
|
||||||
.createQName(ContentModel.PROP_CONTENT.getNamespaceURI(), QName
|
false);
|
||||||
.createValidLocalName(copyName)), false);
|
|
||||||
|
|
||||||
// modify the name of the copy to reflect the new mimetype
|
// modify the name of the copy to reflect the new mimetype
|
||||||
this.nodeService.setProperty(copyNodeRef, ContentModel.PROP_NAME, copyName);
|
this.nodeService.setProperty(copyNodeRef, ContentModel.PROP_NAME, copyName);
|
||||||
@@ -1589,7 +1559,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
Map<String, Object> opts = new HashMap<String, Object>(1);
|
Map<String, Object> opts = new HashMap<String, Object>(1);
|
||||||
opts.put(ImageMagickContentTransformer.KEY_OPTIONS, options != null ? options : "");
|
opts.put(ImageMagickContentTransformer.KEY_OPTIONS, options != null ? options : "");
|
||||||
contentService.getImageTransformer().transform(reader, writer, opts);
|
contentService.getImageTransformer().transform(reader, writer, opts);
|
||||||
transformedNode = newInstance(nodeRef, services, imageResolver, scope);
|
transformedNode = newInstance(nodeRef, services, scope);
|
||||||
}
|
}
|
||||||
catch (NoTransformerException err)
|
catch (NoTransformerException err)
|
||||||
{
|
{
|
||||||
@@ -1664,12 +1634,12 @@ public class Node implements Serializable, Scopeable
|
|||||||
// add the current node as either the document/space as appropriate
|
// add the current node as either the document/space as appropriate
|
||||||
if (this.getIsDocument())
|
if (this.getIsDocument())
|
||||||
{
|
{
|
||||||
model.put("document", new TemplateNode(this.nodeRef, this.services));
|
model.put("document", new TemplateNode(this.nodeRef, this.services, null));
|
||||||
model.put("space", new TemplateNode(getPrimaryParentAssoc().getParentRef(), this.services));
|
model.put("space", new TemplateNode(getPrimaryParentAssoc().getParentRef(), this.services, null));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
model.put("space", new TemplateNode(this.nodeRef, this.services));
|
model.put("space", new TemplateNode(this.nodeRef, this.services, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the supplied args to the 'args' root object
|
// add the supplied args to the 'args' root object
|
||||||
@@ -1718,8 +1688,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
// TODO: DC: Allow debug output of property values - for now it's disabled as this could potentially
|
// TODO: DC: Allow debug output of property values - for now it's disabled as this could potentially
|
||||||
// follow a large network of nodes. Unfortunately, JBPM issues unprotected debug statements
|
// follow a large network of nodes. Unfortunately, JBPM issues unprotected debug statements
|
||||||
// where node.toString is used - will request this is fixed in next release of JBPM.
|
// where node.toString is used - will request this is fixed in next release of JBPM.
|
||||||
return "Node Type: "
|
return "Node Type: " + getType() + "\nNode Properties: " + this.getProperties().size() + "\nNode Aspects: "
|
||||||
+ getType() + "\nNode Properties: " + this.getProperties().size() + "\nNode Aspects: "
|
|
||||||
+ this.getAspects().toString();
|
+ this.getAspects().toString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1782,8 +1751,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
|
|
||||||
if (xpath.length() != 0)
|
if (xpath.length() != 0)
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled()) logger.debug("Executing xpath: " + xpath);
|
||||||
logger.debug("Executing xpath: " + xpath);
|
|
||||||
|
|
||||||
List<NodeRef> nodes = this.services.getSearchService().selectNodes(this.nodeRef, xpath, null,
|
List<NodeRef> nodes = this.services.getSearchService().selectNodes(this.nodeRef, xpath, null,
|
||||||
this.services.getNamespaceService(), false);
|
this.services.getNamespaceService(), false);
|
||||||
@@ -1794,7 +1762,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
if (nodes.size() != 0)
|
if (nodes.size() != 0)
|
||||||
{
|
{
|
||||||
result = new Node[1];
|
result = new Node[1];
|
||||||
result[0] = newInstance(nodes.get(0), this.services, this.imageResolver, this.scope);
|
result[0] = newInstance(nodes.get(0), this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// or all the results
|
// or all the results
|
||||||
@@ -1804,7 +1772,7 @@ public class Node implements Serializable, Scopeable
|
|||||||
for (int i = 0; i < nodes.size(); i++)
|
for (int i = 0; i < nodes.size(); i++)
|
||||||
{
|
{
|
||||||
NodeRef ref = nodes.get(i);
|
NodeRef ref = nodes.get(i);
|
||||||
result[i] = newInstance(ref, this.services, this.imageResolver, this.scope);
|
result[i] = newInstance(ref, this.services, this.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -77,7 +77,7 @@ public abstract class BasePathResultsMap extends BaseTemplateMap
|
|||||||
if (nodes.size() != 0)
|
if (nodes.size() != 0)
|
||||||
{
|
{
|
||||||
result = new ArrayList<TemplateNode>(1);
|
result = new ArrayList<TemplateNode>(1);
|
||||||
result.add(new TemplateNode(nodes.get(0), this.services));
|
result.add(new TemplateNode(nodes.get(0), this.services, this.parent.getImageResolver()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// or all the results
|
// or all the results
|
||||||
@@ -86,7 +86,7 @@ public abstract class BasePathResultsMap extends BaseTemplateMap
|
|||||||
result = new ArrayList<TemplateNode>(nodes.size());
|
result = new ArrayList<TemplateNode>(nodes.size());
|
||||||
for (NodeRef ref : nodes)
|
for (NodeRef ref : nodes)
|
||||||
{
|
{
|
||||||
result.add(new TemplateNode(ref, this.services));
|
result.add(new TemplateNode(ref, this.services, this.parent.getImageResolver()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,7 +75,7 @@ public abstract class BaseSearchResultsMap extends BaseTemplateMap
|
|||||||
NodeRef nodeRef = row.getNodeRef();
|
NodeRef nodeRef = row.getNodeRef();
|
||||||
if (!nodeRefs.contains(nodeRef))
|
if (!nodeRefs.contains(nodeRef))
|
||||||
{
|
{
|
||||||
nodes.add(new TemplateNode(nodeRef, services));
|
nodes.add(new TemplateNode(nodeRef, services, this.parent.getImageResolver()));
|
||||||
nodeRefs.add(nodeRef);
|
nodeRefs.add(nodeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -102,7 +102,7 @@ public final class Classification
|
|||||||
ArrayList<CategoryTemplateNode> categoryNodes = new ArrayList<CategoryTemplateNode>(cars.size());
|
ArrayList<CategoryTemplateNode> categoryNodes = new ArrayList<CategoryTemplateNode>(cars.size());
|
||||||
for (ChildAssociationRef car : cars)
|
for (ChildAssociationRef car : cars)
|
||||||
{
|
{
|
||||||
categoryNodes.add(new CategoryTemplateNode(car.getChildRef(), this.services));
|
categoryNodes.add(new CategoryTemplateNode(car.getChildRef(), this.services, this.imageResolver));
|
||||||
}
|
}
|
||||||
return categoryNodes;
|
return categoryNodes;
|
||||||
}
|
}
|
||||||
|
@@ -309,18 +309,18 @@ public class FreeMarkerProcessor implements TemplateProcessor
|
|||||||
Map<String, Object> model = new HashMap<String, Object>(16, 1.0f);
|
Map<String, Object> model = new HashMap<String, Object>(16, 1.0f);
|
||||||
|
|
||||||
// supply the Company Home space as "companyhome"
|
// supply the Company Home space as "companyhome"
|
||||||
model.put("companyhome", new TemplateNode(companyHome, services));
|
model.put("companyhome", new TemplateNode(companyHome, services, imageResolver));
|
||||||
|
|
||||||
// supply the users Home Space as "userhome"
|
// supply the users Home Space as "userhome"
|
||||||
model.put("userhome", new TemplateNode(userHome, services));
|
model.put("userhome", new TemplateNode(userHome, services, imageResolver));
|
||||||
|
|
||||||
// supply the current user Node as "person"
|
// supply the current user Node as "person"
|
||||||
model.put("person", new TemplateNode(person, services));
|
model.put("person", new TemplateNode(person, services, imageResolver));
|
||||||
|
|
||||||
// add the template itself as "template" if it comes from content on a node
|
// add the template itself as "template" if it comes from content on a node
|
||||||
if (template != null)
|
if (template != null)
|
||||||
{
|
{
|
||||||
model.put("template", new TemplateNode(template, services));
|
model.put("template", new TemplateNode(template, services, imageResolver));
|
||||||
}
|
}
|
||||||
|
|
||||||
// current date/time is useful to have and isn't supplied by FreeMarker by default
|
// current date/time is useful to have and isn't supplied by FreeMarker by default
|
||||||
|
@@ -116,7 +116,7 @@ public class TemplateServiceImplTest extends TestCase
|
|||||||
// create test model
|
// create test model
|
||||||
Map model = new HashMap(7, 1.0f);
|
Map model = new HashMap(7, 1.0f);
|
||||||
|
|
||||||
model.put("root", new TemplateNode(root, serviceRegistry));
|
model.put("root", new TemplateNode(root, serviceRegistry, null));
|
||||||
|
|
||||||
// execute on test template
|
// execute on test template
|
||||||
String output = templateService.processTemplate("freemarker", TEMPLATE_1, model);
|
String output = templateService.processTemplate("freemarker", TEMPLATE_1, model);
|
||||||
|
@@ -93,6 +93,7 @@ public class TemplateNode implements Serializable
|
|||||||
private String displayPath = null;
|
private String displayPath = null;
|
||||||
private String mimetype = null;
|
private String mimetype = null;
|
||||||
private Long size = null;
|
private Long size = null;
|
||||||
|
protected TemplateImageResolver imageResolver = null;
|
||||||
private TemplateNode parent = null;
|
private TemplateNode parent = null;
|
||||||
private ChildAssociationRef primaryParentAssoc = null;
|
private ChildAssociationRef primaryParentAssoc = null;
|
||||||
private Boolean isCategory = null;
|
private Boolean isCategory = null;
|
||||||
@@ -108,7 +109,7 @@ public class TemplateNode implements Serializable
|
|||||||
* @param services The ServiceRegistry the TemplateNode can use to access services
|
* @param services The ServiceRegistry the TemplateNode can use to access services
|
||||||
* @param resolver Image resolver to use to retrieve icons
|
* @param resolver Image resolver to use to retrieve icons
|
||||||
*/
|
*/
|
||||||
public TemplateNode(NodeRef nodeRef, ServiceRegistry services)
|
public TemplateNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver)
|
||||||
{
|
{
|
||||||
if (nodeRef == null)
|
if (nodeRef == null)
|
||||||
{
|
{
|
||||||
@@ -123,6 +124,7 @@ public class TemplateNode implements Serializable
|
|||||||
this.nodeRef = nodeRef;
|
this.nodeRef = nodeRef;
|
||||||
this.id = nodeRef.getId();
|
this.id = nodeRef.getId();
|
||||||
this.services = services;
|
this.services = services;
|
||||||
|
this.imageResolver = resolver;
|
||||||
|
|
||||||
this.properties = new QNameMap<String, Object>(this.services.getNamespaceService());
|
this.properties = new QNameMap<String, Object>(this.services.getNamespaceService());
|
||||||
}
|
}
|
||||||
@@ -131,14 +133,6 @@ public class TemplateNode implements Serializable
|
|||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Node API
|
// Node API
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the image resolver
|
|
||||||
*/
|
|
||||||
public TemplateImageResolver getImageResolver()
|
|
||||||
{
|
|
||||||
return imageResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The GUID for the node
|
* @return The GUID for the node
|
||||||
*/
|
*/
|
||||||
@@ -208,7 +202,7 @@ public class TemplateNode implements Serializable
|
|||||||
for (ChildAssociationRef ref : childRefs)
|
for (ChildAssociationRef ref : childRefs)
|
||||||
{
|
{
|
||||||
// create our Node representation from the NodeRef
|
// create our Node representation from the NodeRef
|
||||||
TemplateNode child = new TemplateNode(ref.getChildRef(), this.services);
|
TemplateNode child = new TemplateNode(ref.getChildRef(), this.services, this.imageResolver);
|
||||||
this.children.add(child);
|
this.children.add(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +229,7 @@ public class TemplateNode implements Serializable
|
|||||||
nodes = new ArrayList<TemplateNode>(4);
|
nodes = new ArrayList<TemplateNode>(4);
|
||||||
this.assocs.put(ref.getTypeQName().toString(), nodes);
|
this.assocs.put(ref.getTypeQName().toString(), nodes);
|
||||||
}
|
}
|
||||||
nodes.add( new TemplateNode(ref.getTargetRef(), this.services) );
|
nodes.add( new TemplateNode(ref.getTargetRef(), this.services, this.imageResolver) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +252,7 @@ public class TemplateNode implements Serializable
|
|||||||
{
|
{
|
||||||
// NodeRef object properties are converted to new TemplateNode objects
|
// NodeRef object properties are converted to new TemplateNode objects
|
||||||
// so they can be used as objects within a template
|
// so they can be used as objects within a template
|
||||||
propValue = new TemplateNode(((NodeRef)propValue), this.services);
|
propValue = new TemplateNode(((NodeRef)propValue), this.services, this.imageResolver);
|
||||||
}
|
}
|
||||||
else if (propValue instanceof ContentData)
|
else if (propValue instanceof ContentData)
|
||||||
{
|
{
|
||||||
@@ -392,7 +386,7 @@ public class TemplateNode implements Serializable
|
|||||||
// handle root node (no parent!)
|
// handle root node (no parent!)
|
||||||
if (parentRef != null)
|
if (parentRef != null)
|
||||||
{
|
{
|
||||||
parent = new TemplateNode(parentRef, this.services);
|
parent = new TemplateNode(parentRef, this.services, this.imageResolver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,17 +542,53 @@ public class TemplateNode implements Serializable
|
|||||||
* @return the small icon image for this node
|
* @return the small icon image for this node
|
||||||
*/
|
*/
|
||||||
public String getIcon16()
|
public String getIcon16()
|
||||||
|
{
|
||||||
|
if (this.imageResolver != null)
|
||||||
|
{
|
||||||
|
if (getIsDocument())
|
||||||
|
{
|
||||||
|
return this.imageResolver.resolveImagePathForName(getName(), true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "/images/icons/space_small.gif";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return "/images/filetypes/_default.gif";
|
return "/images/filetypes/_default.gif";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the large icon image for this node
|
* @return the large icon image for this node
|
||||||
*/
|
*/
|
||||||
public String getIcon32()
|
public String getIcon32()
|
||||||
|
{
|
||||||
|
if (this.imageResolver != null)
|
||||||
|
{
|
||||||
|
if (getIsDocument())
|
||||||
|
{
|
||||||
|
return this.imageResolver.resolveImagePathForName(getName(), false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String icon = (String)getProperties().get("app:icon");
|
||||||
|
if (icon != null)
|
||||||
|
{
|
||||||
|
return "/images/icons/" + icon + ".gif";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "/images/icons/space-icon-default.gif";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return "/images/filetypes32/_default.gif";
|
return "/images/filetypes32/_default.gif";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
@@ -661,6 +691,14 @@ public class TemplateNode implements Serializable
|
|||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Misc helpers
|
// Misc helpers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the image resolver instance used by this node
|
||||||
|
*/
|
||||||
|
public TemplateImageResolver getImageResolver()
|
||||||
|
{
|
||||||
|
return this.imageResolver;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override Object.toString() to provide useful debug output
|
* Override Object.toString() to provide useful debug output
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user