From fd3a6d6e971943711861a49fd279ef49928927e4 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Mon, 23 Jun 2008 09:48:22 +0000 Subject: [PATCH] Preference Service git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@9538 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/application-context.xml | 1 + config/alfresco/model/contentModel.xml | 9 + .../alfresco/preference-service-context.xml | 56 +++ config/alfresco/script-services-context.xml | 3 - .../java/org/alfresco/model/ContentModel.java | 5 + .../preference/PreferenceServiceImpl.java | 369 ++++++++++++++++++ .../preference/PreferenceServiceImplTest.java | 174 +++++++++ .../script/ScriptPreferenceService.java | 145 +++++++ .../script/test_preferenceService.js | 39 ++ .../cmr/preference/PreferenceService.java | 45 +++ 10 files changed, 843 insertions(+), 3 deletions(-) create mode 100644 config/alfresco/preference-service-context.xml create mode 100644 source/java/org/alfresco/repo/preference/PreferenceServiceImpl.java create mode 100644 source/java/org/alfresco/repo/preference/PreferenceServiceImplTest.java create mode 100644 source/java/org/alfresco/repo/preference/script/ScriptPreferenceService.java create mode 100644 source/java/org/alfresco/repo/preference/script/test_preferenceService.js create mode 100644 source/java/org/alfresco/service/cmr/preference/PreferenceService.java diff --git a/config/alfresco/application-context.xml b/config/alfresco/application-context.xml index 9d4ea0121e..3fb6faaaa2 100644 --- a/config/alfresco/application-context.xml +++ b/config/alfresco/application-context.xml @@ -42,6 +42,7 @@ + diff --git a/config/alfresco/model/contentModel.xml b/config/alfresco/model/contentModel.xml index 001b8e78c0..b21722edf3 100644 --- a/config/alfresco/model/contentModel.xml +++ b/config/alfresco/model/contentModel.xml @@ -862,6 +862,15 @@ + + Preferences + + + d:content + + + + diff --git a/config/alfresco/preference-service-context.xml b/config/alfresco/preference-service-context.xml new file mode 100644 index 0000000000..bc96159453 --- /dev/null +++ b/config/alfresco/preference-service-context.xml @@ -0,0 +1,56 @@ + + + + + + + + + org.alfresco.service.cmr.preference.PreferenceService + + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + + + + + + + + + + + preferenceService + + + + + + diff --git a/config/alfresco/script-services-context.xml b/config/alfresco/script-services-context.xml index d11981dffc..e610ce2e7a 100644 --- a/config/alfresco/script-services-context.xml +++ b/config/alfresco/script-services-context.xml @@ -33,9 +33,6 @@ - - - diff --git a/source/java/org/alfresco/model/ContentModel.java b/source/java/org/alfresco/model/ContentModel.java index 4ffc828d56..b869116ef4 100644 --- a/source/java/org/alfresco/model/ContentModel.java +++ b/source/java/org/alfresco/model/ContentModel.java @@ -247,6 +247,10 @@ public interface ContentModel // Thumbnailed Aspect static final QName ASPECT_THUMBNAILED = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "thumbnailed"); static final QName ASSOC_THUMBNAILS = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "thumbnails"); + + // Preference Aspect + static final QName ASPECT_PREFERENCES = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "preferences"); + static final QName PROP_PREFERENCE_VALUES = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "preferenceValues"); // // User Model Definitions @@ -272,4 +276,5 @@ public interface ContentModel static final QName PROP_AUTHORITY_NAME = QName.createQName(USER_MODEL_URI, "authorityName"); static final QName ASSOC_MEMBER = QName.createQName(USER_MODEL_URI, "member"); static final QName PROP_MEMBERS = QName.createQName(USER_MODEL_URI, "members"); + } diff --git a/source/java/org/alfresco/repo/preference/PreferenceServiceImpl.java b/source/java/org/alfresco/repo/preference/PreferenceServiceImpl.java new file mode 100644 index 0000000000..c851b3b986 --- /dev/null +++ b/source/java/org/alfresco/repo/preference/PreferenceServiceImpl.java @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.preference; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.service.cmr.preference.PreferenceService; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.security.PersonService; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Preference Service Implementation + * + * @author Roy Wetherall + */ +public class PreferenceServiceImpl implements PreferenceService +{ + /** Node service */ + private NodeService nodeService; + + /** Content service */ + private ContentService contentService; + + /** Person service */ + private PersonService personService; + + /** Permission Service */ + private PermissionService permissionService; + + /** Authentication Service */ + private AuthenticationComponent authenticationComponent; + + /** + * Set the node service + * + * @param nodeService the node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * Set the content service + * + * @param contentService the content service + */ + public void setContentService(ContentService contentService) + { + this.contentService = contentService; + } + + /** + * Set the person service + * + * @param personService the person service + */ + public void setPersonService(PersonService personService) + { + this.personService = personService; + } + + /** + * Set the permission service + * + * @param permissionService the permission service + */ + public void setPermissionService(PermissionService permissionService) + { + this.permissionService = permissionService; + } + + /** + * Set the authentication component + * + * @param authenticationComponent the authentication component + */ + public void setAuthenticationComponent(AuthenticationComponent authenticationComponent) + { + this.authenticationComponent = authenticationComponent; + } + + /** + * @see org.alfresco.service.cmr.preference.PreferenceService#getPreferences(java.lang.String) + */ + public Map getPreferences(String userName) + { + return getPreferences(userName, null); + } + + /** + * @see org.alfresco.repo.person.PersonService#getPreferences(java.lang.String, java.lang.String) + */ + public Map getPreferences(String userName, String preferenceFilter) + { + Map preferences = new HashMap(20); + + // Get the user node reference + NodeRef personNodeRef = this.personService.getPerson(userName); + if (personNodeRef == null) + { + throw new AlfrescoRuntimeException("Can not get preferences for " + userName + " because he/she does not exist."); + } + + try + { + // Check for preferences aspect + if (this.nodeService.hasAspect(personNodeRef, ContentModel.ASPECT_PREFERENCES) == true) + { + // Get the preferences for this user + JSONObject jsonPrefs = new JSONObject(); + ContentReader reader = this.contentService.getReader(personNodeRef, ContentModel.PROP_PREFERENCE_VALUES); + if (reader != null) + { + jsonPrefs = new JSONObject(reader.getContentString()); + } + + // Build hash from preferences stored in the repository + Iterator keys = jsonPrefs.keys(); + while (keys.hasNext()) + { + String key = (String)keys.next(); + + if (preferenceFilter == null || + preferenceFilter.length() == 0 || + matchPreferenceNames(key, preferenceFilter) == true) + { + preferences.put(key, (Serializable)jsonPrefs.get(key)); + } + } + } + } + catch (JSONException exception) + { + throw new AlfrescoRuntimeException("Can not get preferences for " + userName + " because there was an error pasing the JSON data.", exception); + } + + return preferences; + } + + /** + * Matches the preference name to the partial preference name provided + * + * @param name preference name + * @param matchTo match to the partial preference name provided + * @return boolean true if matches, false otherwise + */ + private boolean matchPreferenceNames(String name, String matchTo) + { + boolean result = true; + + // Split strings + name = name.replace(".", "-"); + String[] nameArr = name.split("-"); + matchTo = matchTo.replace(".", "-"); + String[] matchToArr = matchTo.split("-"); + + int index = 0; + for (String matchToElement : matchToArr) + { + if (matchToElement.equals(nameArr[index]) == false) + { + result = false; + break; + } + index ++; + } + + return result; + } + + /** + * @see org.alfresco.repo.person.PersonService#setPreferences(java.lang.String, java.util.HashMap) + */ + public void setPreferences(final String userName, final Map preferences) + { + // Get the user node reference + final NodeRef personNodeRef = this.personService.getPerson(userName); + if (personNodeRef == null) + { + throw new AlfrescoRuntimeException("Can not update preferences for " + userName + " because he/she does not exist."); + } + + // Can only set preferences if the currently logged in user matches the user name being updated or + // the user already has write permissions on the person node + String currentUserName = AuthenticationUtil.getCurrentUserName(); + if (authenticationComponent.isSystemUserName(currentUserName) == true || + permissionService.hasPermission(personNodeRef, PermissionService.WRITE) == AccessStatus.ALLOWED || + userName.equals(currentUserName) == true) + { + AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + // Apply the preferences aspect if required + if (PreferenceServiceImpl.this.nodeService.hasAspect(personNodeRef, ContentModel.ASPECT_PREFERENCES) == false) + { + PreferenceServiceImpl.this.nodeService.addAspect(personNodeRef, ContentModel.ASPECT_PREFERENCES, null); + } + + try + { + // Get the current preferences + JSONObject jsonPrefs = new JSONObject(); + ContentReader reader = PreferenceServiceImpl.this.contentService.getReader(personNodeRef, ContentModel.PROP_PREFERENCE_VALUES); + if (reader != null) + { + jsonPrefs = new JSONObject(reader.getContentString()); + } + + // Update with the new preference values + for (Map.Entry entry : preferences.entrySet()) + { + jsonPrefs.put(entry.getKey(), entry.getValue()); + } + + // Save the updated preferences + ContentWriter contentWriter = PreferenceServiceImpl.this.contentService.getWriter(personNodeRef, ContentModel.PROP_PREFERENCE_VALUES, true); + contentWriter.setEncoding("UTF-8"); + contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentWriter.putContent(jsonPrefs.toString()); + } + catch (JSONException exception) + { + throw new AlfrescoRuntimeException("Can not update preferences for " + userName + " because there was an error pasing the JSON data.", exception); + } + + return null; + } + + }, "admin"); + } + else + { + // The current user does not have sufficient permissions to update the preferences for this user + throw new AlfrescoRuntimeException("The current user " + currentUserName + " does not have sufficient permissions to update the preferences of the user " + userName); + } + } + + /** + * @see org.alfresco.service.cmr.preference.PreferenceService#clearPreferences(java.lang.String) + */ + public void clearPreferences(String userName) + { + clearPreferences(userName, null); + } + + /** + * @see org.alfresco.repo.person.PersonService#clearPreferences(java.lang.String, java.lang.String) + */ + public void clearPreferences(final String userName, final String preferenceFilter) + { + // Get the user node reference + final NodeRef personNodeRef = this.personService.getPerson(userName); + if (personNodeRef == null) + { + throw new AlfrescoRuntimeException("Can not update preferences for " + userName + " because he/she does not exist."); + } + + // Can only set preferences if the currently logged in user matches the user name being updated or + // the user already has write permissions on the person node + String currentUserName = AuthenticationUtil.getCurrentUserName(); + if (authenticationComponent.isSystemUserName(currentUserName) == true || + permissionService.hasPermission(personNodeRef, PermissionService.WRITE) == AccessStatus.ALLOWED || + userName.equals(currentUserName) == true) + { + AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + if (PreferenceServiceImpl.this.nodeService.hasAspect(personNodeRef, ContentModel.ASPECT_PREFERENCES) == true) + { + try + { + JSONObject jsonPrefs = new JSONObject(); + if (preferenceFilter != null && preferenceFilter.length() != 0) + { + // Get the current preferences + ContentReader reader = PreferenceServiceImpl.this.contentService.getReader(personNodeRef, ContentModel.PROP_PREFERENCE_VALUES); + if (reader != null) + { + jsonPrefs = new JSONObject(reader.getContentString()); + } + + // Remove the prefs that match the filter + List removeKeys = new ArrayList(10); + Iterator keys = jsonPrefs.keys(); + while (keys.hasNext()) + { + String key = (String)keys.next(); + + if (preferenceFilter == null || + preferenceFilter.length() == 0 || + matchPreferenceNames(key, preferenceFilter) == true) + { + removeKeys.add(key); + } + } + for (String removeKey : removeKeys) + { + jsonPrefs.remove(removeKey); + } + } + + // Put the updated JSON back into the repo + ContentWriter contentWriter = PreferenceServiceImpl.this.contentService.getWriter(personNodeRef, ContentModel.PROP_PREFERENCE_VALUES, true); + contentWriter.setEncoding("UTF-8"); + contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentWriter.putContent(jsonPrefs.toString()); + } + catch (JSONException exception) + { + throw new AlfrescoRuntimeException("Can not update preferences for " + userName + " because there was an error pasing the JSON data.", exception); + } + } + + return null; + } + }, "admin"); + } + else + { + // The current user does not have sufficient permissions to update the preferences for this user + throw new AlfrescoRuntimeException("The current user " + currentUserName + " does not have sufficient permissions to update the preferences of the user " + userName); + } + } + +} diff --git a/source/java/org/alfresco/repo/preference/PreferenceServiceImplTest.java b/source/java/org/alfresco/repo/preference/PreferenceServiceImplTest.java new file mode 100644 index 0000000000..5570f0fb84 --- /dev/null +++ b/source/java/org/alfresco/repo/preference/PreferenceServiceImplTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.preference; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.jscript.ClasspathScriptLocation; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.service.cmr.preference.PreferenceService; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.ScriptLocation; +import org.alfresco.service.cmr.repository.ScriptService; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.util.BaseAlfrescoSpringTest; +import org.alfresco.util.TestWithUserUtils; + +/** + * Thumbnail service implementation unit test + * + * @author Roy Wetherall + */ +public class PreferenceServiceImplTest extends BaseAlfrescoSpringTest +{ + private static final String USER_ONE = "userOne"; + private static final String USER_BAD = "userBad"; + + private ScriptService scriptService; + private NodeService nodeService; + private AuthenticationComponent authenticationComponent; + private PreferenceService preferenceService; + private PersonService personService; + private ContentService contentService; + + /** + * Called during the transaction setup + */ + protected void onSetUpInTransaction() throws Exception + { + super.onSetUpInTransaction(); + + // Get the required services + this.scriptService = (ScriptService)this.applicationContext.getBean("ScriptService"); + this.nodeService = (NodeService)this.applicationContext.getBean("NodeService"); + this.authenticationComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent"); + this.preferenceService = (PreferenceService)this.applicationContext.getBean("PreferenceService"); + this.personService = (PersonService)this.applicationContext.getBean("PersonService"); + this.contentService = (ContentService)this.applicationContext.getBean("ContentService"); + + // Do the test's as userOne + TestWithUserUtils.authenticateUser(USER_ONE, "PWD", this.authenticationService, this.authenticationComponent); + } + + public void testPreferences() throws Exception + { + //assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName()); + + // Try and get preferences before they have been set + Map prefs = this.preferenceService.getPreferences(USER_ONE); + assertNotNull(prefs); + assertEquals(0, prefs.size()); + + //assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName()); + + // Lets set some preferences for the user + prefs = new HashMap(5); + prefs.put("alfresco.one.alpha", "string"); + prefs.put("alfresco.one.beta", 100); + prefs.put("alfresco.two.alpha", 3.142); + prefs.put("alfresco.two.beta", this.rootNodeRef); + prefs.put("alfresco.two.gamma", new Date()); + prefs.put("atTheRoot", "thisIsAtTheRoot"); + this.preferenceService.setPreferences(USER_ONE, prefs); + + // assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName()); + + NodeRef personNodeRef = this.personService.getPerson(USER_ONE); + ContentReader reader = this.contentService.getReader(personNodeRef, ContentModel.PROP_PREFERENCE_VALUES); + System.out.println("JSON: " + reader.getContentString()); + + // Try and get all the preferences + prefs = this.preferenceService.getPreferences(USER_ONE, null); + assertNotNull(prefs); + assertEquals(6, prefs.size()); + + // Try and get some of the preferences + prefs = this.preferenceService.getPreferences(USER_ONE, "alfresco.two"); + assertNotNull(prefs); + assertEquals(3, prefs.size()); + + //assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName()); + + // Clear some of the preferences + this.preferenceService.clearPreferences(USER_ONE, "alfresco.two"); + prefs = this.preferenceService.getPreferences(USER_ONE, null); + assertNotNull(prefs); + assertEquals(3, prefs.size()); + + //assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName()); + + // Clear all the preferences + this.preferenceService.clearPreferences(USER_ONE); + prefs = this.preferenceService.getPreferences(USER_ONE); + assertNotNull(prefs); + assertEquals(0, prefs.size()); + + // assertEquals(USER_ONE, AuthenticationUtil.getCurrentUserName()); + + } + + public void xtestBadUser() + { + //assertEquals(USER_ONE, authenticationComponent.getCurrentUserName()); + + try + { + // Lets set some preferences for the user + Map prefs = new HashMap(5); + prefs.put("alfresco.one.alpha", "string"); + prefs.put("alfresco.one.beta", 100); + prefs.put("alfresco.two.alpha", 3.142); + prefs.put("alfresco.two.beta", this.rootNodeRef); + prefs.put("alfresco.two.gamma", new Date()); + prefs.put("atTheRoot", "thisIsAtTheRoot"); + this.preferenceService.setPreferences(USER_BAD, prefs); + + fail("This should have raised an exception since we are trying to update preferences that are not our own!"); + } + catch (Exception exception) + { + // this is OK :) + } + + } + + // == Test the JavaScript API == + + public void testJSAPI() throws Exception + { + //assertEquals(USER_ONE, authenticationComponent.getCurrentUserName()); + + ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/preference/script/test_preferenceService.js"); + this.scriptService.executeScript(location, new HashMap(0)); + } +} diff --git a/source/java/org/alfresco/repo/preference/script/ScriptPreferenceService.java b/source/java/org/alfresco/repo/preference/script/ScriptPreferenceService.java new file mode 100644 index 0000000000..55b7fd74bd --- /dev/null +++ b/source/java/org/alfresco/repo/preference/script/ScriptPreferenceService.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.preference.script; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.repo.jscript.BaseScopableProcessorExtension; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.preference.PreferenceService; +import org.mozilla.javascript.IdScriptableObject; +import org.mozilla.javascript.NativeObject; + +/** + * @author Roy Wetherall + */ +public class ScriptPreferenceService extends BaseScopableProcessorExtension +{ + private ServiceRegistry services; + + /** Preference Service */ + private PreferenceService preferenceService; + + public void setServiceRegistry(ServiceRegistry services) + { + this.services = services; + } + + public void setPreferenceService(PreferenceService preferenceService) + { + this.preferenceService = preferenceService; + } + + public NativeObject getPreferences(String userName) + { + return getPreferences(userName, null); + } + + public NativeObject getPreferences(String userName, String preferenceFilter) + { + Map prefs = this.preferenceService.getPreferences(userName, preferenceFilter); + NativeObject result = new NativeObject(); + + for (Map.Entry entry : prefs.entrySet()) + { + String[] keys = entry.getKey().replace(".", "-").split("-"); + setPrefValue(keys, entry.getValue(), result); + } + + return result; + } + + private void setPrefValue(String[] keys, Serializable value, NativeObject object) + { + NativeObject currentObject = object; + int index = 0; + for (String key : keys) + { + if (index == keys.length-1) + { + currentObject.put(key, currentObject, value); + } + else + { + NativeObject newObject = null; + Object temp = currentObject.get(key, currentObject); + if (temp == null || temp instanceof NativeObject == false) + { + newObject = new NativeObject(); + currentObject.put(key, currentObject, newObject); + } + else + { + newObject = (NativeObject)temp; + } + currentObject = newObject; + } + + index ++; + } + } + + public void setPreferences(String userName, NativeObject preferences) + { + Map values = new HashMap(10); + getPrefValues(preferences, null, values); + + this.preferenceService.setPreferences(userName, values); + } + + private void getPrefValues(NativeObject currentObject, String currentKey, Map values) + { + Object[] ids = currentObject.getIds(); + for (Object id : ids) + { + String key = getAppendedKey(currentKey, id.toString()); + Object value = currentObject.get(id.toString(), currentObject); + if (value instanceof NativeObject) + { + getPrefValues((NativeObject)value, key, values); + } + else + { + values.put(key, (Serializable)value); + } + } + } + + private String getAppendedKey(String currentKey, String key) + { + StringBuffer buffer = new StringBuffer(64); + if (currentKey != null && currentKey.length() != 0) + { + buffer.append(currentKey).append(".").append(key); + } + else + { + buffer.append(key); + } + return buffer.toString(); + } +} diff --git a/source/java/org/alfresco/repo/preference/script/test_preferenceService.js b/source/java/org/alfresco/repo/preference/script/test_preferenceService.js new file mode 100644 index 0000000000..4b8d10ef29 --- /dev/null +++ b/source/java/org/alfresco/repo/preference/script/test_preferenceService.js @@ -0,0 +1,39 @@ +function testPreferences() +{ + var preferences = new Object(); + preferences.myValue = "myValue"; + preferences.comp1 = new Object(); + preferences.comp1.value1 = "value1"; + preferences.comp1.value2 = 12; + + preferenceService.setPreferences("userOne", preferences); + + var result = preferenceService.getPreferences("userOne"); + + test.assertNotNull(result); + test.assertEquals("myValue", result.myValue); + test.assertEquals("value1", result.comp1.value1); + test.assertEquals(12, result.comp1.value2); + + preferences = new Object(); + preferences.comp2 = new Object(); + preferences.comp2.value1 = "value1"; + preferences.comp2.value2 = 3.142; + preferences.comp1 = new Object(); + preferences.comp1.value1 = "changed"; + preferences.comp1.value2 = 1001; + + preferenceService.setPreferences("userOne", preferences); + + result = preferenceService.getPreferences("userOne"); + + test.assertNotNull(result); + test.assertEquals("myValue", result.myValue); + test.assertEquals("changed", result.comp1.value1); + test.assertEquals(1001, result.comp1.value2); + test.assertEquals("value1", result.comp2.value1); + test.assertEquals(3.142, result.comp2.value2); +} + +// Execute test's +testPreferences(); \ No newline at end of file diff --git a/source/java/org/alfresco/service/cmr/preference/PreferenceService.java b/source/java/org/alfresco/service/cmr/preference/PreferenceService.java new file mode 100644 index 0000000000..27884e41a9 --- /dev/null +++ b/source/java/org/alfresco/service/cmr/preference/PreferenceService.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.service.cmr.preference; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author Roy Wetherall + */ +public interface PreferenceService +{ + Map getPreferences(String userName); + + Map getPreferences(String userName, String preferenceFilter); + + void setPreferences(String userName, Map preferences); + + void clearPreferences(String userName); + + void clearPreferences(String userName, String preferenceFilter); + +}