View Javadoc
1   package org.argeo.cms.ui.widgets;
2   
3   import javax.jcr.Item;
4   import javax.jcr.Node;
5   import javax.jcr.Property;
6   import javax.jcr.RepositoryException;
7   import javax.jcr.Session;
8   
9   import org.argeo.cms.CmsException;
10  import org.argeo.cms.ui.util.CmsUiUtils;
11  import org.eclipse.swt.SWT;
12  import org.eclipse.swt.widgets.Composite;
13  
14  /** A composite which can (optionally) manage a JCR Item. */
15  public class JcrComposite extends Composite {
16  	private static final long serialVersionUID = -1447009015451153367L;
17  
18  	private final Session session;
19  
20  	private String nodeId;
21  	private String property = null;
22  	private Node cache;
23  
24  	/** Regular composite constructor. No layout is set. */
25  	public JcrComposite(Composite parent, int style) {
26  		super(parent, style);
27  		session = null;
28  		nodeId = null;
29  	}
30  
31  	public JcrComposite(Composite parent, int style, Item item)
32  			throws RepositoryException {
33  		this(parent, style, item, false);
34  	}
35  
36  	public JcrComposite(Composite parent, int style, Item item,
37  			boolean cacheImmediately) throws RepositoryException {
38  		super(parent, style);
39  		this.session = item.getSession();
40  		if (!cacheImmediately && (SWT.READ_ONLY == (style & SWT.READ_ONLY))) {
41  			// (useless?) optimization: we only save a pointer to the session,
42  			// not even a reference to the item
43  			this.nodeId = null;
44  		} else {
45  			Node node;
46  			Property property = null;
47  			if (item instanceof Node) {
48  				node = (Node) item;
49  			} else {// Property
50  				property = (Property) item;
51  				if (property.isMultiple())// TODO manage property index
52  					throw new CmsException(
53  							"Multiple properties not supported yet.");
54  				this.property = property.getName();
55  				node = property.getParent();
56  			}
57  			this.nodeId = node.getIdentifier();
58  			if (cacheImmediately)
59  				this.cache = node;
60  		}
61  		setLayout(CmsUiUtils.noSpaceGridLayout());
62  	}
63  
64  	public synchronized Node getNode() {
65  		try {
66  			if (!itemIsNode())
67  				throw new CmsException("Item is not a Node");
68  			return getNodeInternal();
69  		} catch (RepositoryException e) {
70  			throw new CmsException("Cannot get node " + nodeId, e);
71  		}
72  	}
73  
74  	private synchronized Node getNodeInternal() throws RepositoryException {
75  		if (cache != null)
76  			return cache;
77  		else if (session != null)
78  			if (nodeId != null)
79  				return session.getNodeByIdentifier(nodeId);
80  			else
81  				return null;
82  		else
83  			return null;
84  	}
85  
86  	public synchronized Property getProperty() {
87  		try {
88  			if (itemIsNode())
89  				throw new CmsException("Item is not a Property");
90  			Node node = getNodeInternal();
91  			if (!node.hasProperty(property))
92  				throw new CmsException("Property " + property
93  						+ " is not set on " + node);
94  			return node.getProperty(property);
95  		} catch (RepositoryException e) {
96  			throw new CmsException("Cannot get property " + property
97  					+ " from node " + nodeId, e);
98  		}
99  	}
100 
101 	public synchronized Boolean itemIsNode() {
102 		return property == null;
103 	}
104 
105 	/** Set/update the cache or change the node */
106 	public synchronized void setNode(Node node) throws RepositoryException {
107 		if (!itemIsNode())
108 			throw new CmsException("Cannot set a Node on a Property");
109 
110 		if (node == null) {// clear cache
111 			this.cache = null;
112 			return;
113 		}
114 
115 		if (session == null || session != node.getSession())// check session
116 			throw new CmsException("Uncompatible session");
117 
118 		if (nodeId == null || !nodeId.equals(node.getIdentifier())) {
119 			nodeId = node.getIdentifier();
120 			cache = node;
121 			itemUpdated();
122 		} else {
123 			cache = node;// set/update cache
124 		}
125 	}
126 
127 	/** Set/update the cache or change the property */
128 	public synchronized void setProperty(Property prop)
129 			throws RepositoryException {
130 		if (itemIsNode())
131 			throw new CmsException("Cannot set a Property on a Node");
132 
133 		if (prop == null) {// clear cache
134 			this.cache = null;
135 			return;
136 		}
137 
138 		if (session == null || session != prop.getSession())// check session
139 			throw new CmsException("Uncompatible session");
140 
141 		Node node = prop.getNode();
142 		if (nodeId == null || !nodeId.equals(node.getIdentifier())
143 				|| !property.equals(prop.getName())) {
144 			nodeId = node.getIdentifier();
145 			property = prop.getName();
146 			cache = node;
147 			itemUpdated();
148 		} else {
149 			cache = node;// set/update cache
150 		}
151 	}
152 
153 	public synchronized String getNodeId() {
154 		return nodeId;
155 	}
156 
157 	/** Change the node, does nothing if same. */
158 	public synchronized void setNodeId(String nodeId)
159 			throws RepositoryException {
160 		if (this.nodeId != null && this.nodeId.equals(nodeId))
161 			return;
162 		this.nodeId = nodeId;
163 		if (cache != null)
164 			cache = session.getNodeByIdentifier(this.nodeId);
165 		itemUpdated();
166 	}
167 
168 	protected synchronized void itemUpdated() {
169 		layout();
170 	}
171 
172 	public Session getSession() {
173 		return session;
174 	}
175 }