You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by be...@apache.org on 2013/07/04 13:18:04 UTC
[2/2] git commit: move JCR storage code over to dedicated module
move JCR storage code over to dedicated module
Project: http://git-wip-us.apache.org/repos/asf/mina-vysper/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-vysper/commit/46f1a8ef
Tree: http://git-wip-us.apache.org/repos/asf/mina-vysper/tree/46f1a8ef
Diff: http://git-wip-us.apache.org/repos/asf/mina-vysper/diff/46f1a8ef
Branch: refs/heads/master
Commit: 46f1a8eff08244af21510262a84fc5b4fb4331af
Parents: 3515de6
Author: Bernd Fondermann <be...@brainlounge.de>
Authored: Thu Jul 4 13:15:08 2013 +0200
Committer: Bernd Fondermann <be...@brainlounge.de>
Committed: Thu Jul 4 13:15:08 2013 +0200
----------------------------------------------------------------------
server/core/pom.xml | 14 -
.../apache/vysper/storage/jcr/JcrStorage.java | 130 ----------
.../vysper/storage/jcr/JcrStorageException.java | 41 ---
.../storage/jcr/JcrStorageProviderRegistry.java | 41 ---
.../JcrPrivateDataPersistenceManager.java | 91 -------
.../storage/jcr/roster/JcrRosterManager.java | 257 -------------------
.../storage/jcr/user/JcrUserManagement.java | 118 ---------
.../JcrVcardTempPersistenceManager.java | 92 -------
.../apache/vysper/storage/jcr/JcrStorage.java | 130 ++++++++++
.../vysper/storage/jcr/JcrStorageException.java | 41 +++
.../storage/jcr/JcrStorageProviderRegistry.java | 41 +++
.../JcrPrivateDataPersistenceManager.java | 91 +++++++
.../storage/jcr/roster/JcrRosterManager.java | 257 +++++++++++++++++++
.../storage/jcr/user/JcrUserManagement.java | 118 +++++++++
.../JcrVcardTempPersistenceManager.java | 92 +++++++
15 files changed, 770 insertions(+), 784 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/core/pom.xml
----------------------------------------------------------------------
diff --git a/server/core/pom.xml b/server/core/pom.xml
index 5def5c3..11c4cfa 100644
--- a/server/core/pom.xml
+++ b/server/core/pom.xml
@@ -67,20 +67,6 @@
<artifactId>mina-core</artifactId>
</dependency>
-<!-- TODO remove... -->
- <dependency>
- <groupId>javax.jcr</groupId>
- <artifactId>jcr</artifactId>
- <optional>true</optional>
- </dependency>
-
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-core</artifactId>
- <optional>true</optional>
- </dependency>
-<!-- ...TODO remove -->
-
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorage.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorage.java b/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorage.java
deleted file mode 100644
index 670877c..0000000
--- a/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorage.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.vysper.storage.jcr;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-import org.apache.jackrabbit.core.TransientRepository;
-import org.apache.vysper.xmpp.addressing.Entity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * back-end stuff for JCR, used by the semantic specific adapters
- * @author The Apache MINA Project (dev@mina.apache.org)
- */
-public class JcrStorage {
-
- final Logger logger = LoggerFactory.getLogger(JcrStorage.class);
-
- protected static JcrStorage jcrStorageSingleton;
-
- protected JcrStorage() {
- super();
- // protected
- }
-
- public static JcrStorage getInstance() {
- synchronized (JcrStorage.class) {
- if (jcrStorageSingleton == null)
- jcrStorageSingleton = new JcrStorage();
- return jcrStorageSingleton;
- }
- }
-
- protected Session session = null;
-
- public Session getRepositorySession() throws JcrStorageException {
- if (session != null)
- return session;
- try {
- Repository repository = new TransientRepository();
- session = repository.login(new SimpleCredentials("xmpp-admin", "adminpassword".toCharArray()));
- return session;
- } catch (Exception e) {
- throw new JcrStorageException(e);
- }
- }
-
- public Node getRootNode() throws JcrStorageException {
- try {
- return getRepositorySession().getRootNode();
- } catch (RepositoryException e) {
- throw new JcrStorageException(e);
- }
- }
-
- public Node getEntityNode(Entity bareEntity, String namespace, boolean createIfMissing) throws JcrStorageException {
- bareEntity = bareEntity.getBareJID(); // make it really sure
- if (namespace != null)
- namespace = namespace.replace(':', '_');
- final String path = "/accountentity/" + bareEntity.getFullQualifiedName()
- + (namespace != null ? "/" + namespace : "");
- if (!itemExists(path)) {
- if (!createIfMissing)
- return null;
- Node accountEntityNode = getOrCreate(getRootNode(), "accountentity");
- Node entityNode = getOrCreate(accountEntityNode, bareEntity.getFullQualifiedName());
- if (namespace != null)
- entityNode = getOrCreate(entityNode, namespace);
- return entityNode;
- } else {
- try {
- return (Node) getRepositorySession().getItem(path);
- } catch (RepositoryException e) {
- throw new JcrStorageException(e);
- }
- }
- }
-
- private boolean itemExists(String absolutePath) throws JcrStorageException {
- try {
- return getRepositorySession().itemExists(absolutePath);
- } catch (RepositoryException e) {
- throw new JcrStorageException(e);
- } catch (JcrStorageException e) {
- throw e;
- }
- }
-
- protected Node getOrCreate(Node parent, String nodeName) throws JcrStorageException {
- Node childNode;
- try {
- childNode = parent.getNode(nodeName);
- } catch (RepositoryException e) {
- childNode = null;
- }
- if (childNode == null) {
- try {
- childNode = parent.addNode(nodeName);
- parent.save();
- childNode.save();
- logger.info("JCR node created: " + childNode);
- } catch (RepositoryException e) {
- throw new JcrStorageException(e);
- }
- }
- return childNode;
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorageException.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorageException.java b/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorageException.java
deleted file mode 100644
index d4747c5..0000000
--- a/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorageException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.vysper.storage.jcr;
-
-/**
- * @author The Apache MINA Project (dev@mina.apache.org)
- */
-public class JcrStorageException extends Exception {
- public JcrStorageException() {
- super();
- }
-
- public JcrStorageException(String message) {
- super(message);
- }
-
- public JcrStorageException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public JcrStorageException(Throwable cause) {
- super(cause);
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorageProviderRegistry.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorageProviderRegistry.java b/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorageProviderRegistry.java
deleted file mode 100644
index d4393d7..0000000
--- a/server/core/src/main/java/org/apache/vysper/storage/jcr/JcrStorageProviderRegistry.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.vysper.storage.jcr;
-
-import org.apache.vysper.storage.OpenStorageProviderRegistry;
-import org.apache.vysper.storage.jcr.privatedata.JcrPrivateDataPersistenceManager;
-import org.apache.vysper.storage.jcr.roster.JcrRosterManager;
-import org.apache.vysper.storage.jcr.user.JcrUserManagement;
-import org.apache.vysper.storage.jcr.vcardtemp.JcrVcardTempPersistenceManager;
-
-/**
- *
- * @author The Apache MINA Project (dev@mina.apache.org)
- */
-public class JcrStorageProviderRegistry extends OpenStorageProviderRegistry {
-
- public JcrStorageProviderRegistry() {
- add(new JcrUserManagement(JcrStorage.getInstance()));
- add(new JcrRosterManager(JcrStorage.getInstance()));
- add(new JcrVcardTempPersistenceManager(JcrStorage.getInstance()));
- add(new JcrPrivateDataPersistenceManager(JcrStorage.getInstance()));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/core/src/main/java/org/apache/vysper/storage/jcr/privatedata/JcrPrivateDataPersistenceManager.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/storage/jcr/privatedata/JcrPrivateDataPersistenceManager.java b/server/core/src/main/java/org/apache/vysper/storage/jcr/privatedata/JcrPrivateDataPersistenceManager.java
deleted file mode 100644
index 6a7544d..0000000
--- a/server/core/src/main/java/org/apache/vysper/storage/jcr/privatedata/JcrPrivateDataPersistenceManager.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.vysper.storage.jcr.privatedata;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.vysper.storage.jcr.JcrStorage;
-import org.apache.vysper.storage.jcr.JcrStorageException;
-import org.apache.vysper.xmpp.addressing.Entity;
-import org.apache.vysper.xmpp.modules.extension.xep0049_privatedata.PrivateDataPersistenceManager;
-import org.apache.vysper.xmpp.protocol.NamespaceURIs;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @author The Apache MINA Project (dev@mina.apache.org)
- */
-public class JcrPrivateDataPersistenceManager implements PrivateDataPersistenceManager {
-
- final Logger logger = LoggerFactory.getLogger(JcrPrivateDataPersistenceManager.class);
-
- protected JcrStorage jcrStorage;
-
- public JcrPrivateDataPersistenceManager(JcrStorage jcrStorage) {
- this.jcrStorage = jcrStorage;
- }
-
- public boolean isAvailable() {
- Session session = null;
- try {
- session = jcrStorage.getRepositorySession();
- return session != null;
- } catch (JcrStorageException e) {
- return false;
- }
- }
-
- public String getPrivateData(Entity entity, String key) {
- Node entityNode = getEntityNodeSave(entity, false);
- if (entityNode == null)
- return null;
- try {
- return entityNode.getProperty(key).getString();
- } catch (RepositoryException e) {
- return null;
- }
- }
-
- public boolean setPrivateData(Entity entity, String key, String xml) {
- Node entityNode = getEntityNodeSave(entity, true);
- try {
- entityNode.setProperty(key, xml);
- entityNode.save();
- logger.info("JCR node created: " + entityNode);
- return true;
- } catch (RepositoryException e) {
- return false;
- }
- }
-
- private Node getEntityNodeSave(Entity entity, boolean createIfMissing) {
- Node entityNode;
- try {
- entityNode = jcrStorage.getEntityNode(entity.getBareJID(), NamespaceURIs.PRIVATE_DATA, createIfMissing);
- } catch (JcrStorageException e) {
- return null;
- }
- if (entityNode == null)
- return null;
- return entityNode;
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/core/src/main/java/org/apache/vysper/storage/jcr/roster/JcrRosterManager.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/storage/jcr/roster/JcrRosterManager.java b/server/core/src/main/java/org/apache/vysper/storage/jcr/roster/JcrRosterManager.java
deleted file mode 100644
index dbb92d7..0000000
--- a/server/core/src/main/java/org/apache/vysper/storage/jcr/roster/JcrRosterManager.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.vysper.storage.jcr.roster;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.apache.vysper.storage.jcr.JcrStorage;
-import org.apache.vysper.storage.jcr.JcrStorageException;
-import org.apache.vysper.xmpp.addressing.Entity;
-import org.apache.vysper.xmpp.addressing.EntityFormatException;
-import org.apache.vysper.xmpp.addressing.EntityImpl;
-import org.apache.vysper.xmpp.modules.roster.AskSubscriptionType;
-import org.apache.vysper.xmpp.modules.roster.MutableRoster;
-import org.apache.vysper.xmpp.modules.roster.Roster;
-import org.apache.vysper.xmpp.modules.roster.RosterException;
-import org.apache.vysper.xmpp.modules.roster.RosterGroup;
-import org.apache.vysper.xmpp.modules.roster.RosterItem;
-import org.apache.vysper.xmpp.modules.roster.SubscriptionType;
-import org.apache.vysper.xmpp.modules.roster.persistence.AbstractRosterManager;
-import org.apache.vysper.xmpp.protocol.NamespaceURIs;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * roster items are stored for contacts in the following path:
- * /accountentity/user@vysper.org/jabber_iq_roster/contact@vysper.org
- * all item properties besides contact jid (which is used as a node name)
- * are stored as node properties
- *
- * @author The Apache MINA Project (dev@mina.apache.org)
- */
-public class JcrRosterManager extends AbstractRosterManager {
-
- final Logger logger = LoggerFactory.getLogger(JcrRosterManager.class);
-
- protected JcrStorage jcrStorage;
-
- public JcrRosterManager(JcrStorage jcrStorage) {
- this.jcrStorage = jcrStorage;
- }
-
- /*package*/static Node retrieveRosterNode(JcrStorage jcrStorage, Entity bareJid) {
- try {
- if (jcrStorage.getEntityNode(bareJid, null, false) == null)
- return null;
- return jcrStorage.getEntityNode(bareJid, NamespaceURIs.JABBER_IQ_ROSTER, true);
- } catch (JcrStorageException e) {
- return null;
- }
- }
-
- @Override
- protected Roster retrieveRosterInternal(Entity bareJid) {
- final Node rosterNode = retrieveRosterNode(jcrStorage, bareJid);
-
- MutableRoster roster = new MutableRoster();
-
- NodeIterator nodes = null;
- try {
- nodes = rosterNode.getNodes();
- } catch (RepositoryException e) {
- return roster; // empty roster object
- }
- while (nodes != null && nodes.hasNext()) {
- Node node = nodes.nextNode();
-
- String contactJidString = null;
- try {
- contactJidString = node.getName();
- } catch (RepositoryException e) {
- logger.warn("when loading roster for user {} cannot read node name for node id = " + node.toString());
- }
- logger.warn("try now loading contact " + contactJidString + " from node " + node.toString());
- EntityImpl contactJid = null;
- if (contactJidString != null) {
- try {
- contactJid = EntityImpl.parse(contactJidString);
- } catch (EntityFormatException e) {
- logger.warn("when loading roster for user {} parsing contact jid {}", bareJid, contactJidString);
- }
- }
- if (contactJid == null) {
- logger.warn("when loading roster for user {}, skipping a contact due to missing or unparsable jid",
- bareJid);
- continue;
- }
-
- String name = readAttribute(node, "name");
- String typeString = readAttribute(node, "type");
- SubscriptionType subscriptionType = null;
- try {
- subscriptionType = SubscriptionType.valueOf(typeString == null ? "NONE" : typeString.toUpperCase());
- } catch (IllegalArgumentException e) {
- logger.warn("when loading roster for user " + bareJid + ", contact " + contactJid
- + " misses a subscription type", bareJid, contactJid);
- }
- String askTypeString = readAttribute(node, "askType");
- AskSubscriptionType askSubscriptionType = AskSubscriptionType.NOT_SET;
- try {
- if (askTypeString != null)
- askSubscriptionType = AskSubscriptionType.valueOf(askTypeString);
- } catch (IllegalArgumentException e) {
- logger.warn("when loading roster for user " + bareJid.getFullQualifiedName() + ", contact "
- + contactJid.getFullQualifiedName() + ", the ask subscription type is unparsable. skipping!");
- continue; // don't return it, don't set a default!
- }
-
- List<RosterGroup> groups = new ArrayList<RosterGroup>();
- // TODO read groups
-
- RosterItem item = new RosterItem(contactJid, name, subscriptionType, askSubscriptionType, groups);
- logger.info("item loaded for " + bareJid.getFullQualifiedName() + ": " + item.toString());
- roster.addItem(item);
- }
- return roster;
- }
-
- private String readAttribute(Node node, String propertyName) {
- try {
- Property property = node.getProperty(propertyName);
- if (property == null)
- return null;
- return property.getString();
- } catch (RepositoryException e) {
- return null;
- }
- }
-
- @Override
- protected Roster addNewRosterInternal(Entity jid) {
- return new MutableRoster();
- }
-
- @Override
- public void addContact(Entity jid, RosterItem rosterItem) throws RosterException {
- if (jid == null)
- throw new RosterException("jid not provided");
- if (rosterItem.getJid() == null)
- throw new RosterException("contact jid not provided");
-
- // TODO think about concurrent updates
-
- Entity contactJid = rosterItem.getJid().getBareJID();
- Node contactNode = getOrCreateContactNode(jid, contactJid);
- try {
- setOrRemoveAttribute(contactNode, "name", rosterItem.getName());
- String subscriptionTypeValue = rosterItem.getSubscriptionType() == null ? null : rosterItem
- .getSubscriptionType().value();
- setOrRemoveAttribute(contactNode, "type", subscriptionTypeValue);
- String askSubscriptionTypeValue = null;
- if (rosterItem.getAskSubscriptionType() != null
- && rosterItem.getAskSubscriptionType() != AskSubscriptionType.NOT_SET) {
- askSubscriptionTypeValue = rosterItem.getAskSubscriptionType().value();
- }
- setOrRemoveAttribute(contactNode, "askType", askSubscriptionTypeValue);
- contactNode.save();
- logger.info("JCR node created/updated: " + contactNode);
- } catch (RepositoryException e) {
- throw new RosterException("failed to add contact node to roster for user = " + jid.getFullQualifiedName()
- + " and contact jid = " + rosterItem.getJid().getFullQualifiedName(), e);
- }
- }
-
- private void setOrRemoveAttribute(Node contactNode, String attributeName, String attributeValue)
- throws RepositoryException {
- if (attributeValue != null)
- contactNode.setProperty(attributeName, attributeValue);
- else if (contactNode.hasProperty(attributeName))
- contactNode.setProperty(attributeName, (String) null);
- }
-
- private Node getOrCreateContactNode(Entity jid, Entity contactJid) throws RosterException {
- Node entityNode = null;
- try {
- entityNode = jcrStorage.getEntityNode(jid, NamespaceURIs.JABBER_IQ_ROSTER, true);
- } catch (JcrStorageException e) {
- throw new RosterException("failed to create roster store for " + jid.getFullQualifiedName(), e);
- }
- Node contactNode = null;
- try {
- contactNode = entityNode.getNode(contactJid.getFullQualifiedName());
- } catch (RepositoryException e) {
- // not exists, create
- try {
- contactNode = entityNode.addNode(contactJid.getFullQualifiedName());
- entityNode.save();
- } catch (RepositoryException addNodeEx) {
- throw new RosterException("failed to add contact node to roster for user = "
- + jid.getFullQualifiedName() + " and contact jid = " + contactJid.getFullQualifiedName(),
- addNodeEx);
- }
-
- }
- return contactNode;
- }
-
- @Override
- public void removeContact(Entity jidUser, Entity jidContact) throws RosterException {
- if (jidUser == null)
- throw new RosterException("jid not provided");
- if (jidContact == null)
- throw new RosterException("contact jid not provided");
- Node rosterNode = null;
- try {
- rosterNode = jcrStorage.getEntityNode(jidUser, NamespaceURIs.JABBER_IQ_ROSTER, false);
- } catch (JcrStorageException e) {
- throw new RosterException("failed to retrieve roster store for " + jidUser.getFullQualifiedName(), e);
- }
- if (rosterNode == null)
- return; // done, no contacts anyway. oops
-
- NodeIterator nodes = null;
- try {
- nodes = rosterNode.getNodes("contact");
- } catch (RepositoryException e) {
- return; // failed to find any contacts, done.
- }
- boolean foundOne = false;
- while (nodes != null && nodes.hasNext()) {
- Node node = nodes.nextNode();
- String contactJidString = readAttribute(node, "jid");
- if (contactJidString != null && contactJidString.equals(jidContact.getFullQualifiedName())) {
- foundOne = true;
- try {
- node.remove();
- } catch (RepositoryException e) {
- logger.warn("failed to remove from roster for user {} the contact jid " + jidContact, jidUser, e);
- }
- }
- }
- if (!foundOne)
- logger.warn("failed to remove from roster for user " + jidUser + " the contact jid " + jidContact);
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/core/src/main/java/org/apache/vysper/storage/jcr/user/JcrUserManagement.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/storage/jcr/user/JcrUserManagement.java b/server/core/src/main/java/org/apache/vysper/storage/jcr/user/JcrUserManagement.java
deleted file mode 100644
index 0f5da9f..0000000
--- a/server/core/src/main/java/org/apache/vysper/storage/jcr/user/JcrUserManagement.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.vysper.storage.jcr.user;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-
-import org.apache.vysper.storage.jcr.JcrStorage;
-import org.apache.vysper.storage.jcr.JcrStorageException;
-import org.apache.vysper.xmpp.addressing.Entity;
-import org.apache.vysper.xmpp.addressing.EntityFormatException;
-import org.apache.vysper.xmpp.addressing.EntityImpl;
-import org.apache.vysper.xmpp.authentication.AccountCreationException;
-import org.apache.vysper.xmpp.authentication.AccountManagement;
-import org.apache.vysper.xmpp.authentication.UserAuthentication;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author The Apache MINA Project (dev@mina.apache.org)
- */
-public class JcrUserManagement implements UserAuthentication, AccountManagement {
-
- final Logger logger = LoggerFactory.getLogger(JcrUserManagement.class);
-
- protected JcrStorage jcrStorage;
-
- private static final String CREDENTIALS_NAMESPACE = "vysper_internal_credentials";
-
- public JcrUserManagement(JcrStorage jcrStorage) {
- this.jcrStorage = jcrStorage;
- }
-
- public boolean verifyCredentials(Entity jid, String passwordCleartext, Object credentials) {
- if (passwordCleartext == null)
- return false;
- try {
- final Node credentialsNode = jcrStorage.getEntityNode(jid, CREDENTIALS_NAMESPACE, false);
- if (credentialsNode == null)
- return false;
- final Property property = credentialsNode.getProperty("password");
- if (property == null)
- return false;
- final String password = property.getValue().getString();
- return passwordCleartext.equals(password);
- } catch (Exception e) {
- return false;
- }
- }
-
- public boolean verifyCredentials(String username, String passwordCleartext, Object credentials) {
- try {
- return verifyCredentials(EntityImpl.parse(username), passwordCleartext, credentials);
- } catch (EntityFormatException e) {
- return false;
- }
- }
-
- public boolean verifyAccountExists(Entity jid) {
- try {
- return jcrStorage.getEntityNode(jid, CREDENTIALS_NAMESPACE, false) != null;
- } catch (JcrStorageException e) {
- return false;
- }
- }
-
- public void addUser(Entity username, String password) throws AccountCreationException {
- // if already existent, don't create, throw error
- try {
- if (jcrStorage.getEntityNode(username, CREDENTIALS_NAMESPACE, false) != null) {
- throw new AccountCreationException("account already exists: " + username.getFullQualifiedName());
- }
- } catch (JcrStorageException e) {
- throw new AccountCreationException("account exists check failed for " + username.getFullQualifiedName(), e);
- }
- // now, finally, create
- try {
- final Node credentialsNode = jcrStorage.getEntityNode(username, CREDENTIALS_NAMESPACE, true);
- credentialsNode.setProperty("password", password);
- credentialsNode.save();
- logger.info("JCR node created: " + credentialsNode);
- } catch (Exception e) {
- // TODO remove account?
- throw new AccountCreationException("failed to create the account set credentials", e);
- }
-
- }
-
- public void changePassword(Entity username, String password) throws AccountCreationException {
- try {
- final Node credentialsNode = jcrStorage.getEntityNode(username, CREDENTIALS_NAMESPACE, false);
- credentialsNode.setProperty("password", password);
- credentialsNode.save();
- logger.info("JCR password changed: " + credentialsNode);
- } catch (Exception e) {
- // TODO remove account?
- throw new AccountCreationException("failed to create the account set credentials", e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/core/src/main/java/org/apache/vysper/storage/jcr/vcardtemp/JcrVcardTempPersistenceManager.java
----------------------------------------------------------------------
diff --git a/server/core/src/main/java/org/apache/vysper/storage/jcr/vcardtemp/JcrVcardTempPersistenceManager.java b/server/core/src/main/java/org/apache/vysper/storage/jcr/vcardtemp/JcrVcardTempPersistenceManager.java
deleted file mode 100644
index 293bad5..0000000
--- a/server/core/src/main/java/org/apache/vysper/storage/jcr/vcardtemp/JcrVcardTempPersistenceManager.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.vysper.storage.jcr.vcardtemp;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.vysper.storage.jcr.JcrStorage;
-import org.apache.vysper.storage.jcr.JcrStorageException;
-import org.apache.vysper.xmpp.addressing.Entity;
-import org.apache.vysper.xmpp.modules.extension.xep0054_vcardtemp.VcardTempPersistenceManager;
-import org.apache.vysper.xmpp.protocol.NamespaceURIs;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author The Apache MINA Project (dev@mina.apache.org)
- */
-public class JcrVcardTempPersistenceManager implements VcardTempPersistenceManager {
-
- final Logger logger = LoggerFactory.getLogger(JcrVcardTempPersistenceManager.class);
-
- protected JcrStorage jcrStorage;
-
- public JcrVcardTempPersistenceManager(JcrStorage jcrStorage) {
- this.jcrStorage = jcrStorage;
- }
-
- public boolean isAvailable() {
- Session session = null;
- try {
- session = jcrStorage.getRepositorySession();
- return session != null;
- } catch (JcrStorageException e) {
- return false;
- }
- }
-
- public String getVcard(Entity entity) {
- Node entityNode = getEntityNodeSave(entity, false);
- if (entityNode == null)
- return null;
- try {
- return entityNode.getProperty("content").getString();
- } catch (RepositoryException e) {
- return null;
- }
- }
-
- private Node getEntityNodeSave(Entity entity, boolean createIfMissing) {
- Node entityNode;
- try {
- entityNode = jcrStorage.getEntityNode(entity.getBareJID(), NamespaceURIs.VCARD_TEMP, createIfMissing);
- } catch (JcrStorageException e) {
- return null;
- }
- if (entityNode == null)
- return null;
- return entityNode;
- }
-
- public boolean setVcard(Entity entity, String xml) {
- Node entityNode = getEntityNodeSave(entity, true);
- try {
- entityNode.setProperty("content", xml);
- entityNode.save();
- logger.info("JCR node created: " + entityNode);
- return true;
- } catch (RepositoryException e) {
- return false;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorage.java
----------------------------------------------------------------------
diff --git a/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorage.java b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorage.java
new file mode 100644
index 0000000..670877c
--- /dev/null
+++ b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorage.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.vysper.storage.jcr;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.jackrabbit.core.TransientRepository;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * back-end stuff for JCR, used by the semantic specific adapters
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class JcrStorage {
+
+ final Logger logger = LoggerFactory.getLogger(JcrStorage.class);
+
+ protected static JcrStorage jcrStorageSingleton;
+
+ protected JcrStorage() {
+ super();
+ // protected
+ }
+
+ public static JcrStorage getInstance() {
+ synchronized (JcrStorage.class) {
+ if (jcrStorageSingleton == null)
+ jcrStorageSingleton = new JcrStorage();
+ return jcrStorageSingleton;
+ }
+ }
+
+ protected Session session = null;
+
+ public Session getRepositorySession() throws JcrStorageException {
+ if (session != null)
+ return session;
+ try {
+ Repository repository = new TransientRepository();
+ session = repository.login(new SimpleCredentials("xmpp-admin", "adminpassword".toCharArray()));
+ return session;
+ } catch (Exception e) {
+ throw new JcrStorageException(e);
+ }
+ }
+
+ public Node getRootNode() throws JcrStorageException {
+ try {
+ return getRepositorySession().getRootNode();
+ } catch (RepositoryException e) {
+ throw new JcrStorageException(e);
+ }
+ }
+
+ public Node getEntityNode(Entity bareEntity, String namespace, boolean createIfMissing) throws JcrStorageException {
+ bareEntity = bareEntity.getBareJID(); // make it really sure
+ if (namespace != null)
+ namespace = namespace.replace(':', '_');
+ final String path = "/accountentity/" + bareEntity.getFullQualifiedName()
+ + (namespace != null ? "/" + namespace : "");
+ if (!itemExists(path)) {
+ if (!createIfMissing)
+ return null;
+ Node accountEntityNode = getOrCreate(getRootNode(), "accountentity");
+ Node entityNode = getOrCreate(accountEntityNode, bareEntity.getFullQualifiedName());
+ if (namespace != null)
+ entityNode = getOrCreate(entityNode, namespace);
+ return entityNode;
+ } else {
+ try {
+ return (Node) getRepositorySession().getItem(path);
+ } catch (RepositoryException e) {
+ throw new JcrStorageException(e);
+ }
+ }
+ }
+
+ private boolean itemExists(String absolutePath) throws JcrStorageException {
+ try {
+ return getRepositorySession().itemExists(absolutePath);
+ } catch (RepositoryException e) {
+ throw new JcrStorageException(e);
+ } catch (JcrStorageException e) {
+ throw e;
+ }
+ }
+
+ protected Node getOrCreate(Node parent, String nodeName) throws JcrStorageException {
+ Node childNode;
+ try {
+ childNode = parent.getNode(nodeName);
+ } catch (RepositoryException e) {
+ childNode = null;
+ }
+ if (childNode == null) {
+ try {
+ childNode = parent.addNode(nodeName);
+ parent.save();
+ childNode.save();
+ logger.info("JCR node created: " + childNode);
+ } catch (RepositoryException e) {
+ throw new JcrStorageException(e);
+ }
+ }
+ return childNode;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorageException.java
----------------------------------------------------------------------
diff --git a/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorageException.java b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorageException.java
new file mode 100644
index 0000000..d4747c5
--- /dev/null
+++ b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorageException.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.vysper.storage.jcr;
+
+/**
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class JcrStorageException extends Exception {
+ public JcrStorageException() {
+ super();
+ }
+
+ public JcrStorageException(String message) {
+ super(message);
+ }
+
+ public JcrStorageException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public JcrStorageException(Throwable cause) {
+ super(cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorageProviderRegistry.java
----------------------------------------------------------------------
diff --git a/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorageProviderRegistry.java b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorageProviderRegistry.java
new file mode 100644
index 0000000..d4393d7
--- /dev/null
+++ b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/JcrStorageProviderRegistry.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.vysper.storage.jcr;
+
+import org.apache.vysper.storage.OpenStorageProviderRegistry;
+import org.apache.vysper.storage.jcr.privatedata.JcrPrivateDataPersistenceManager;
+import org.apache.vysper.storage.jcr.roster.JcrRosterManager;
+import org.apache.vysper.storage.jcr.user.JcrUserManagement;
+import org.apache.vysper.storage.jcr.vcardtemp.JcrVcardTempPersistenceManager;
+
+/**
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class JcrStorageProviderRegistry extends OpenStorageProviderRegistry {
+
+ public JcrStorageProviderRegistry() {
+ add(new JcrUserManagement(JcrStorage.getInstance()));
+ add(new JcrRosterManager(JcrStorage.getInstance()));
+ add(new JcrVcardTempPersistenceManager(JcrStorage.getInstance()));
+ add(new JcrPrivateDataPersistenceManager(JcrStorage.getInstance()));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/privatedata/JcrPrivateDataPersistenceManager.java
----------------------------------------------------------------------
diff --git a/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/privatedata/JcrPrivateDataPersistenceManager.java b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/privatedata/JcrPrivateDataPersistenceManager.java
new file mode 100644
index 0000000..6a7544d
--- /dev/null
+++ b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/privatedata/JcrPrivateDataPersistenceManager.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.vysper.storage.jcr.privatedata;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.vysper.storage.jcr.JcrStorage;
+import org.apache.vysper.storage.jcr.JcrStorageException;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.modules.extension.xep0049_privatedata.PrivateDataPersistenceManager;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class JcrPrivateDataPersistenceManager implements PrivateDataPersistenceManager {
+
+ final Logger logger = LoggerFactory.getLogger(JcrPrivateDataPersistenceManager.class);
+
+ protected JcrStorage jcrStorage;
+
+ public JcrPrivateDataPersistenceManager(JcrStorage jcrStorage) {
+ this.jcrStorage = jcrStorage;
+ }
+
+ public boolean isAvailable() {
+ Session session = null;
+ try {
+ session = jcrStorage.getRepositorySession();
+ return session != null;
+ } catch (JcrStorageException e) {
+ return false;
+ }
+ }
+
+ public String getPrivateData(Entity entity, String key) {
+ Node entityNode = getEntityNodeSave(entity, false);
+ if (entityNode == null)
+ return null;
+ try {
+ return entityNode.getProperty(key).getString();
+ } catch (RepositoryException e) {
+ return null;
+ }
+ }
+
+ public boolean setPrivateData(Entity entity, String key, String xml) {
+ Node entityNode = getEntityNodeSave(entity, true);
+ try {
+ entityNode.setProperty(key, xml);
+ entityNode.save();
+ logger.info("JCR node created: " + entityNode);
+ return true;
+ } catch (RepositoryException e) {
+ return false;
+ }
+ }
+
+ private Node getEntityNodeSave(Entity entity, boolean createIfMissing) {
+ Node entityNode;
+ try {
+ entityNode = jcrStorage.getEntityNode(entity.getBareJID(), NamespaceURIs.PRIVATE_DATA, createIfMissing);
+ } catch (JcrStorageException e) {
+ return null;
+ }
+ if (entityNode == null)
+ return null;
+ return entityNode;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/roster/JcrRosterManager.java
----------------------------------------------------------------------
diff --git a/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/roster/JcrRosterManager.java b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/roster/JcrRosterManager.java
new file mode 100644
index 0000000..dbb92d7
--- /dev/null
+++ b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/roster/JcrRosterManager.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.vysper.storage.jcr.roster;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.vysper.storage.jcr.JcrStorage;
+import org.apache.vysper.storage.jcr.JcrStorageException;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityFormatException;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.modules.roster.AskSubscriptionType;
+import org.apache.vysper.xmpp.modules.roster.MutableRoster;
+import org.apache.vysper.xmpp.modules.roster.Roster;
+import org.apache.vysper.xmpp.modules.roster.RosterException;
+import org.apache.vysper.xmpp.modules.roster.RosterGroup;
+import org.apache.vysper.xmpp.modules.roster.RosterItem;
+import org.apache.vysper.xmpp.modules.roster.SubscriptionType;
+import org.apache.vysper.xmpp.modules.roster.persistence.AbstractRosterManager;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * roster items are stored for contacts in the following path:
+ * /accountentity/user@vysper.org/jabber_iq_roster/contact@vysper.org
+ * all item properties besides contact jid (which is used as a node name)
+ * are stored as node properties
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class JcrRosterManager extends AbstractRosterManager {
+
+ final Logger logger = LoggerFactory.getLogger(JcrRosterManager.class);
+
+ protected JcrStorage jcrStorage;
+
+ public JcrRosterManager(JcrStorage jcrStorage) {
+ this.jcrStorage = jcrStorage;
+ }
+
+ /*package*/static Node retrieveRosterNode(JcrStorage jcrStorage, Entity bareJid) {
+ try {
+ if (jcrStorage.getEntityNode(bareJid, null, false) == null)
+ return null;
+ return jcrStorage.getEntityNode(bareJid, NamespaceURIs.JABBER_IQ_ROSTER, true);
+ } catch (JcrStorageException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected Roster retrieveRosterInternal(Entity bareJid) {
+ final Node rosterNode = retrieveRosterNode(jcrStorage, bareJid);
+
+ MutableRoster roster = new MutableRoster();
+
+ NodeIterator nodes = null;
+ try {
+ nodes = rosterNode.getNodes();
+ } catch (RepositoryException e) {
+ return roster; // empty roster object
+ }
+ while (nodes != null && nodes.hasNext()) {
+ Node node = nodes.nextNode();
+
+ String contactJidString = null;
+ try {
+ contactJidString = node.getName();
+ } catch (RepositoryException e) {
+ logger.warn("when loading roster for user {} cannot read node name for node id = " + node.toString());
+ }
+ logger.warn("try now loading contact " + contactJidString + " from node " + node.toString());
+ EntityImpl contactJid = null;
+ if (contactJidString != null) {
+ try {
+ contactJid = EntityImpl.parse(contactJidString);
+ } catch (EntityFormatException e) {
+ logger.warn("when loading roster for user {} parsing contact jid {}", bareJid, contactJidString);
+ }
+ }
+ if (contactJid == null) {
+ logger.warn("when loading roster for user {}, skipping a contact due to missing or unparsable jid",
+ bareJid);
+ continue;
+ }
+
+ String name = readAttribute(node, "name");
+ String typeString = readAttribute(node, "type");
+ SubscriptionType subscriptionType = null;
+ try {
+ subscriptionType = SubscriptionType.valueOf(typeString == null ? "NONE" : typeString.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ logger.warn("when loading roster for user " + bareJid + ", contact " + contactJid
+ + " misses a subscription type", bareJid, contactJid);
+ }
+ String askTypeString = readAttribute(node, "askType");
+ AskSubscriptionType askSubscriptionType = AskSubscriptionType.NOT_SET;
+ try {
+ if (askTypeString != null)
+ askSubscriptionType = AskSubscriptionType.valueOf(askTypeString);
+ } catch (IllegalArgumentException e) {
+ logger.warn("when loading roster for user " + bareJid.getFullQualifiedName() + ", contact "
+ + contactJid.getFullQualifiedName() + ", the ask subscription type is unparsable. skipping!");
+ continue; // don't return it, don't set a default!
+ }
+
+ List<RosterGroup> groups = new ArrayList<RosterGroup>();
+ // TODO read groups
+
+ RosterItem item = new RosterItem(contactJid, name, subscriptionType, askSubscriptionType, groups);
+ logger.info("item loaded for " + bareJid.getFullQualifiedName() + ": " + item.toString());
+ roster.addItem(item);
+ }
+ return roster;
+ }
+
+ private String readAttribute(Node node, String propertyName) {
+ try {
+ Property property = node.getProperty(propertyName);
+ if (property == null)
+ return null;
+ return property.getString();
+ } catch (RepositoryException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected Roster addNewRosterInternal(Entity jid) {
+ return new MutableRoster();
+ }
+
+ @Override
+ public void addContact(Entity jid, RosterItem rosterItem) throws RosterException {
+ if (jid == null)
+ throw new RosterException("jid not provided");
+ if (rosterItem.getJid() == null)
+ throw new RosterException("contact jid not provided");
+
+ // TODO think about concurrent updates
+
+ Entity contactJid = rosterItem.getJid().getBareJID();
+ Node contactNode = getOrCreateContactNode(jid, contactJid);
+ try {
+ setOrRemoveAttribute(contactNode, "name", rosterItem.getName());
+ String subscriptionTypeValue = rosterItem.getSubscriptionType() == null ? null : rosterItem
+ .getSubscriptionType().value();
+ setOrRemoveAttribute(contactNode, "type", subscriptionTypeValue);
+ String askSubscriptionTypeValue = null;
+ if (rosterItem.getAskSubscriptionType() != null
+ && rosterItem.getAskSubscriptionType() != AskSubscriptionType.NOT_SET) {
+ askSubscriptionTypeValue = rosterItem.getAskSubscriptionType().value();
+ }
+ setOrRemoveAttribute(contactNode, "askType", askSubscriptionTypeValue);
+ contactNode.save();
+ logger.info("JCR node created/updated: " + contactNode);
+ } catch (RepositoryException e) {
+ throw new RosterException("failed to add contact node to roster for user = " + jid.getFullQualifiedName()
+ + " and contact jid = " + rosterItem.getJid().getFullQualifiedName(), e);
+ }
+ }
+
+ private void setOrRemoveAttribute(Node contactNode, String attributeName, String attributeValue)
+ throws RepositoryException {
+ if (attributeValue != null)
+ contactNode.setProperty(attributeName, attributeValue);
+ else if (contactNode.hasProperty(attributeName))
+ contactNode.setProperty(attributeName, (String) null);
+ }
+
+ private Node getOrCreateContactNode(Entity jid, Entity contactJid) throws RosterException {
+ Node entityNode = null;
+ try {
+ entityNode = jcrStorage.getEntityNode(jid, NamespaceURIs.JABBER_IQ_ROSTER, true);
+ } catch (JcrStorageException e) {
+ throw new RosterException("failed to create roster store for " + jid.getFullQualifiedName(), e);
+ }
+ Node contactNode = null;
+ try {
+ contactNode = entityNode.getNode(contactJid.getFullQualifiedName());
+ } catch (RepositoryException e) {
+ // not exists, create
+ try {
+ contactNode = entityNode.addNode(contactJid.getFullQualifiedName());
+ entityNode.save();
+ } catch (RepositoryException addNodeEx) {
+ throw new RosterException("failed to add contact node to roster for user = "
+ + jid.getFullQualifiedName() + " and contact jid = " + contactJid.getFullQualifiedName(),
+ addNodeEx);
+ }
+
+ }
+ return contactNode;
+ }
+
+ @Override
+ public void removeContact(Entity jidUser, Entity jidContact) throws RosterException {
+ if (jidUser == null)
+ throw new RosterException("jid not provided");
+ if (jidContact == null)
+ throw new RosterException("contact jid not provided");
+ Node rosterNode = null;
+ try {
+ rosterNode = jcrStorage.getEntityNode(jidUser, NamespaceURIs.JABBER_IQ_ROSTER, false);
+ } catch (JcrStorageException e) {
+ throw new RosterException("failed to retrieve roster store for " + jidUser.getFullQualifiedName(), e);
+ }
+ if (rosterNode == null)
+ return; // done, no contacts anyway. oops
+
+ NodeIterator nodes = null;
+ try {
+ nodes = rosterNode.getNodes("contact");
+ } catch (RepositoryException e) {
+ return; // failed to find any contacts, done.
+ }
+ boolean foundOne = false;
+ while (nodes != null && nodes.hasNext()) {
+ Node node = nodes.nextNode();
+ String contactJidString = readAttribute(node, "jid");
+ if (contactJidString != null && contactJidString.equals(jidContact.getFullQualifiedName())) {
+ foundOne = true;
+ try {
+ node.remove();
+ } catch (RepositoryException e) {
+ logger.warn("failed to remove from roster for user {} the contact jid " + jidContact, jidUser, e);
+ }
+ }
+ }
+ if (!foundOne)
+ logger.warn("failed to remove from roster for user " + jidUser + " the contact jid " + jidContact);
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/user/JcrUserManagement.java
----------------------------------------------------------------------
diff --git a/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/user/JcrUserManagement.java b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/user/JcrUserManagement.java
new file mode 100644
index 0000000..0f5da9f
--- /dev/null
+++ b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/user/JcrUserManagement.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.vysper.storage.jcr.user;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+
+import org.apache.vysper.storage.jcr.JcrStorage;
+import org.apache.vysper.storage.jcr.JcrStorageException;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityFormatException;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.authentication.AccountCreationException;
+import org.apache.vysper.xmpp.authentication.AccountManagement;
+import org.apache.vysper.xmpp.authentication.UserAuthentication;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class JcrUserManagement implements UserAuthentication, AccountManagement {
+
+ final Logger logger = LoggerFactory.getLogger(JcrUserManagement.class);
+
+ protected JcrStorage jcrStorage;
+
+ private static final String CREDENTIALS_NAMESPACE = "vysper_internal_credentials";
+
+ public JcrUserManagement(JcrStorage jcrStorage) {
+ this.jcrStorage = jcrStorage;
+ }
+
+ public boolean verifyCredentials(Entity jid, String passwordCleartext, Object credentials) {
+ if (passwordCleartext == null)
+ return false;
+ try {
+ final Node credentialsNode = jcrStorage.getEntityNode(jid, CREDENTIALS_NAMESPACE, false);
+ if (credentialsNode == null)
+ return false;
+ final Property property = credentialsNode.getProperty("password");
+ if (property == null)
+ return false;
+ final String password = property.getValue().getString();
+ return passwordCleartext.equals(password);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public boolean verifyCredentials(String username, String passwordCleartext, Object credentials) {
+ try {
+ return verifyCredentials(EntityImpl.parse(username), passwordCleartext, credentials);
+ } catch (EntityFormatException e) {
+ return false;
+ }
+ }
+
+ public boolean verifyAccountExists(Entity jid) {
+ try {
+ return jcrStorage.getEntityNode(jid, CREDENTIALS_NAMESPACE, false) != null;
+ } catch (JcrStorageException e) {
+ return false;
+ }
+ }
+
+ public void addUser(Entity username, String password) throws AccountCreationException {
+ // if already existent, don't create, throw error
+ try {
+ if (jcrStorage.getEntityNode(username, CREDENTIALS_NAMESPACE, false) != null) {
+ throw new AccountCreationException("account already exists: " + username.getFullQualifiedName());
+ }
+ } catch (JcrStorageException e) {
+ throw new AccountCreationException("account exists check failed for " + username.getFullQualifiedName(), e);
+ }
+ // now, finally, create
+ try {
+ final Node credentialsNode = jcrStorage.getEntityNode(username, CREDENTIALS_NAMESPACE, true);
+ credentialsNode.setProperty("password", password);
+ credentialsNode.save();
+ logger.info("JCR node created: " + credentialsNode);
+ } catch (Exception e) {
+ // TODO remove account?
+ throw new AccountCreationException("failed to create the account set credentials", e);
+ }
+
+ }
+
+ public void changePassword(Entity username, String password) throws AccountCreationException {
+ try {
+ final Node credentialsNode = jcrStorage.getEntityNode(username, CREDENTIALS_NAMESPACE, false);
+ credentialsNode.setProperty("password", password);
+ credentialsNode.save();
+ logger.info("JCR password changed: " + credentialsNode);
+ } catch (Exception e) {
+ // TODO remove account?
+ throw new AccountCreationException("failed to create the account set credentials", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-vysper/blob/46f1a8ef/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/vcardtemp/JcrVcardTempPersistenceManager.java
----------------------------------------------------------------------
diff --git a/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/vcardtemp/JcrVcardTempPersistenceManager.java b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/vcardtemp/JcrVcardTempPersistenceManager.java
new file mode 100644
index 0000000..293bad5
--- /dev/null
+++ b/server/storage/jcr/src/main/java/org/apache/vysper/storage/jcr/vcardtemp/JcrVcardTempPersistenceManager.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.vysper.storage.jcr.vcardtemp;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.vysper.storage.jcr.JcrStorage;
+import org.apache.vysper.storage.jcr.JcrStorageException;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.modules.extension.xep0054_vcardtemp.VcardTempPersistenceManager;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public class JcrVcardTempPersistenceManager implements VcardTempPersistenceManager {
+
+ final Logger logger = LoggerFactory.getLogger(JcrVcardTempPersistenceManager.class);
+
+ protected JcrStorage jcrStorage;
+
+ public JcrVcardTempPersistenceManager(JcrStorage jcrStorage) {
+ this.jcrStorage = jcrStorage;
+ }
+
+ public boolean isAvailable() {
+ Session session = null;
+ try {
+ session = jcrStorage.getRepositorySession();
+ return session != null;
+ } catch (JcrStorageException e) {
+ return false;
+ }
+ }
+
+ public String getVcard(Entity entity) {
+ Node entityNode = getEntityNodeSave(entity, false);
+ if (entityNode == null)
+ return null;
+ try {
+ return entityNode.getProperty("content").getString();
+ } catch (RepositoryException e) {
+ return null;
+ }
+ }
+
+ private Node getEntityNodeSave(Entity entity, boolean createIfMissing) {
+ Node entityNode;
+ try {
+ entityNode = jcrStorage.getEntityNode(entity.getBareJID(), NamespaceURIs.VCARD_TEMP, createIfMissing);
+ } catch (JcrStorageException e) {
+ return null;
+ }
+ if (entityNode == null)
+ return null;
+ return entityNode;
+ }
+
+ public boolean setVcard(Entity entity, String xml) {
+ Node entityNode = getEntityNodeSave(entity, true);
+ try {
+ entityNode.setProperty("content", xml);
+ entityNode.save();
+ logger.info("JCR node created: " + entityNode);
+ return true;
+ } catch (RepositoryException e) {
+ return false;
+ }
+ }
+}