+ protected synchronized Session getWriteSession(String workspace) throws RepositoryException {
+ Session session = writeSessions.get(workspace);
+ if (session == null) {
+ session = login(workspace);
+ writeSessions.put(workspace, session);
+ } else {
+// if ((writeThread != Thread.currentThread()) && session.hasPendingChanges()) {
+// throw new IllegalStateException("Session " + contentSession + " is currently being written to");
+// }
+// writeThread = Thread.currentThread();
+ }
+ return session;
+ }
+
+ public synchronized Node openForEdit(String workspace, String jcrPath) throws RepositoryException {
+ Session session = getWriteSession(workspace);
+ Node node = session.getNode(jcrPath);
+ VersionManager versionManager = session.getWorkspace().getVersionManager();
+
+ Node versionedAncestor = findVersionedAncestor(node);
+ boolean checkedOut = versionManager.isCheckedOut(jcrPath);
+
+ if (versionedAncestor != null) {
+ if (checkedOut) {
+ if (!checkedOutModified.containsKey(workspace))
+ checkedOutModified.put(workspace, new TreeSet<>());
+ checkedOutModified.get(workspace).add(versionedAncestor.getPath());
+ } else {
+ if (!checkedInModified.containsKey(workspace))
+ checkedInModified.put(workspace, new TreeSet<>());
+ checkedInModified.get(workspace).add(versionedAncestor.getPath());
+ versionManager.checkout(versionedAncestor.getPath());
+ }
+ }
+ return node;
+ }
+
+ private Node findVersionedAncestor(Node node) throws RepositoryException {
+ if (node.isNodeType(NodeType.MIX_SIMPLE_VERSIONABLE))
+ return node;
+ Node parent = node.getParent();
+ if (parent == null)
+ return null;
+ return findVersionedAncestor(parent);
+ }
+
+ public synchronized Node freeze(String workspace, String jcrPath) throws RepositoryException {
+ Session session = getWriteSession(workspace);
+ Node node = session.getNode(jcrPath);
+ if (node.isNodeType(NodeType.MIX_SIMPLE_VERSIONABLE)) {
+ VersionManager versionManager = session.getWorkspace().getVersionManager();
+ if (versionManager.isCheckedOut(jcrPath)) {
+ versionManager.checkin(jcrPath);
+ }
+ }
+ return node;
+ }
+
+ public synchronized boolean isOpenForEdit(String workspace, String jcrPath) throws RepositoryException {
+ Session session = getWriteSession(workspace);
+ VersionManager versionManager = session.getWorkspace().getVersionManager();
+ return versionManager.isCheckedOut(jcrPath);
+ }
+
+ public synchronized void persist() throws RepositoryException {
+ for (String workspace : writeSessions.keySet()) {
+ Session session = writeSessions.get(workspace);
+ if (session == null) {
+// assert writeThread == null;
+ assert !checkedOutModified.containsKey(workspace);
+ assert !checkedInModified.containsKey(workspace);
+ return; // nothing to do
+ }
+ session.save();
+ VersionManager versionManager = session.getWorkspace().getVersionManager();
+ if (checkedOutModified.containsKey(workspace))
+ for (String jcrPath : checkedOutModified.get(workspace)) {
+ versionManager.checkpoint(jcrPath);
+ }
+ if (checkedInModified.containsKey(workspace))
+ for (String jcrPath : checkedInModified.get(workspace)) {
+ versionManager.checkin(jcrPath);
+ }
+ Jcr.logout(session);
+ }
+
+ for (Map<String, Session> m : threadSessions.values())
+ for (Session session : m.values())
+ session.refresh(true);
+// writeThread = null;
+ writeSessions.clear();
+ checkedOutModified.clear();
+ checkedInModified.clear();
+ }
+
+ protected Session login(String workspace) {
+ return Subject.doAs(subject, (PrivilegedAction<Session>) () -> {
+ try {
+// String username = CurrentUser.getUsername(subject);
+// SimpleCredentials credentials = new SimpleCredentials(username, new char[0]);
+// credentials.setAttribute(ProvidedSession.class.getName(), contentSession);
+ Session sess = repository.login(workspace);
+ // Jackrabbit specific:
+ ((SessionImpl) sess).setAttribute(ProvidedSession.class.getName(), contentSession);
+ return sess;
+ } catch (RepositoryException e) {
+ throw new IllegalStateException("Cannot log in to " + workspace, e);
+ }
+ });
+ }
+