This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-tenant.git
commit 3cf961f2e853cb6ce1f6d6f49757166d1aa688f4 Author: Felix Meschberger <[email protected]> AuthorDate: Fri Mar 1 07:59:38 2013 +0000 Improve Tenant: - Clarify getName() and getDescription() if properties are missing - Add unit tests - Allow TenantImpl to reload properties - Declare Tenant as provider type interface (not to be implemented by consumers) git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1451511 13f79535-47bb-0310-9956-ffa450edef68 --- src/main/java/org/apache/sling/tenant/Tenant.java | 37 +++-- .../apache/sling/tenant/internal/TenantImpl.java | 15 +- .../sling/tenant/internal/TenantImplTest.java | 179 +++++++++++++++++++++ 3 files changed, 207 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/apache/sling/tenant/Tenant.java b/src/main/java/org/apache/sling/tenant/Tenant.java index 1f32733..04d1dd4 100644 --- a/src/main/java/org/apache/sling/tenant/Tenant.java +++ b/src/main/java/org/apache/sling/tenant/Tenant.java @@ -20,6 +20,8 @@ package org.apache.sling.tenant; import java.util.Iterator; +import aQute.bnd.annotation.ProviderType; + /** * The <code>Tenant</code> interface represents a tenant which may be used to * further customize request and other processing. @@ -28,13 +30,14 @@ import java.util.Iterator; * {@link TenantProvider} interface to be returned for it tenant accessor * methods. */ +@ProviderType public interface Tenant { /** * The name of the {@link #getProperty(String) property} whose string * representation is used as this tenant's {@link #getName() name} (value is * "sling.tenant.name"). - * + * * @see #getName() * @see #getProperty(String) */ @@ -44,7 +47,7 @@ public interface Tenant { * The name of the {@link #getProperty(String) property} whose string * representation is used as this tenant's {@link #getDescription() * description} (value is "sling.tenant.description"). - * + * * @see #getDescription() * @see #getProperty(String) */ @@ -58,21 +61,23 @@ public interface Tenant { */ String getId(); - /** - * Returns the name of the tenant. This is a short name for quickly - * identifying this tenant. This name is not required to be globally unique. - * <p> - * The name of the tenant is the string representation of the - * {@link #PROP_NAME} property. - */ - String getName(); + /** + * Returns the name of the tenant. This is a short name for quickly + * identifying this tenant. This name is not required to be globally unique. + * <p> + * The name of the tenant is the string representation of the + * {@link #PROP_NAME} property or {@code null} if the property is not + * defined. + */ + String getName(); - /** - * Returns a human readable description of this tenant. - * <p> - * The description of the tenant is the string representation of the - * {@link #PROP_DESCRIPTION} property. - */ + /** + * Returns a human readable description of this tenant. + * <p> + * The description of the tenant is the string representation of the + * {@link #PROP_DESCRIPTION} property or {@code null} if the property is not + * defined. + */ String getDescription(); /** diff --git a/src/main/java/org/apache/sling/tenant/internal/TenantImpl.java b/src/main/java/org/apache/sling/tenant/internal/TenantImpl.java index 8ebb946..bf53761 100644 --- a/src/main/java/org/apache/sling/tenant/internal/TenantImpl.java +++ b/src/main/java/org/apache/sling/tenant/internal/TenantImpl.java @@ -32,18 +32,17 @@ import org.apache.sling.tenant.Tenant; * A resource backed tenant implementation. */ class TenantImpl implements Tenant { - private String id; + + private final String id; private ValueMap vm; TenantImpl(Resource resource) { this.id = resource.getName(); - // vm = ResourceUtil.getValueMap(resource); - // create local detached value map - vm = getLocalValueMap(resource); + loadProperties(resource); } - private ValueMap getLocalValueMap(Resource resource) { + void loadProperties(Resource resource) { ValueMap jcrVM = ResourceUtil.getValueMap(resource); Map<String, Object> localMap = new HashMap<String, Object>(); @@ -53,7 +52,7 @@ class TenantImpl implements Tenant { // decoarate it as value map ValueMapDecorator localVM = new ValueMapDecorator(localMap); - return localVM; + this.vm = localVM; } @@ -62,11 +61,11 @@ class TenantImpl implements Tenant { } public String getName() { - return vm.get(Tenant.PROP_NAME, ""); + return vm.get(Tenant.PROP_NAME, String.class); } public String getDescription() { - return vm.get(Tenant.PROP_DESCRIPTION, ""); + return vm.get(Tenant.PROP_DESCRIPTION, String.class); } public Object getProperty(String name) { diff --git a/src/test/java/org/apache/sling/tenant/internal/TenantImplTest.java b/src/test/java/org/apache/sling/tenant/internal/TenantImplTest.java new file mode 100644 index 0000000..b8fd4bf --- /dev/null +++ b/src/test/java/org/apache/sling/tenant/internal/TenantImplTest.java @@ -0,0 +1,179 @@ +/* + * 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.sling.tenant.internal; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import junit.framework.TestCase; + +import org.apache.sling.api.resource.AbstractResource; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceMetadata; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.api.wrappers.ValueMapDecorator; +import org.apache.sling.tenant.Tenant; +import org.junit.Test; + +public class TenantImplTest { + + private static final String t1 = "t1"; + + private static final String t2 = "t2"; + + private static final String pt1 = "/etc/tenants/" + t1; + + private static final String pt2 = "/etc/tenants/" + t2; + + private static final String n1 = "name1"; + + private static final String n2 = "name2"; + + private static final String d1 = "description1"; + + private static final String d2 = "description2"; + + private static final String p1 = "prop1"; + + @SuppressWarnings("serial") + private static final Set<String> propNamesDefault = new HashSet<String>() { + { + add(Tenant.PROP_NAME); + add(Tenant.PROP_DESCRIPTION); + } + }; + + @SuppressWarnings("serial") + private static final Set<String> propNamesTest = new HashSet<String>() { + { + add(p1); + } + }; + + @Test + public void test_id() { + Resource r = new MockResource(pt1, new HashMap<String, Object>()); + Tenant tenant1 = new TenantImpl(r); + + TestCase.assertEquals(t1, tenant1.getId()); + TestCase.assertNull(tenant1.getName()); + TestCase.assertNull(tenant1.getDescription()); + + TestCase.assertFalse(tenant1.getPropertyNames().hasNext()); + + TestCase.assertNull(tenant1.getProperty(Tenant.PROP_NAME)); + TestCase.assertNull(tenant1.getProperty(Tenant.PROP_DESCRIPTION)); + TestCase.assertNull(tenant1.getProperty(p1)); + } + + @Test + public void test_name_description() { + @SuppressWarnings("serial") + Resource r = new MockResource(pt1, new HashMap<String, Object>() { + { + put(Tenant.PROP_NAME, n1); + put(Tenant.PROP_DESCRIPTION, d1); + } + }); + Tenant tenant1 = new TenantImpl(r); + + TestCase.assertEquals(t1, tenant1.getId()); + TestCase.assertEquals(n1, tenant1.getName()); + TestCase.assertEquals(d1, tenant1.getDescription()); + + Iterator<String> pi = tenant1.getPropertyNames(); + TestCase.assertTrue(propNamesDefault.contains(pi.next())); + TestCase.assertTrue(propNamesDefault.contains(pi.next())); + TestCase.assertFalse(pi.hasNext()); + + TestCase.assertEquals(n1, tenant1.getProperty(Tenant.PROP_NAME)); + TestCase.assertEquals(d1, tenant1.getProperty(Tenant.PROP_DESCRIPTION)); + TestCase.assertNull(tenant1.getProperty(p1)); + + } + + @Test + public void test_property() { + @SuppressWarnings("serial") + Resource r = new MockResource(pt1, new HashMap<String, Object>() { + { + put(p1, p1); + } + }); + Tenant tenant1 = new TenantImpl(r); + + TestCase.assertEquals(t1, tenant1.getId()); + TestCase.assertNull(tenant1.getName()); + TestCase.assertNull(tenant1.getDescription()); + + Iterator<String> pi = tenant1.getPropertyNames(); + TestCase.assertTrue(propNamesTest.contains(pi.next())); + TestCase.assertFalse(pi.hasNext()); + + TestCase.assertNull(tenant1.getProperty(Tenant.PROP_NAME)); + TestCase.assertNull(tenant1.getProperty(Tenant.PROP_DESCRIPTION)); + TestCase.assertEquals(p1, tenant1.getProperty(p1)); + } + + private static class MockResource extends AbstractResource { + + private final String path; + + private final Map<String, Object> props; + + MockResource(final String path, final Map<String, Object> props) { + this.path = path; + this.props = props; + } + + public String getPath() { + return path; + } + + public String getResourceType() { + return null; + } + + public String getResourceSuperType() { + return null; + } + + public ResourceMetadata getResourceMetadata() { + return null; + } + + public ResourceResolver getResourceResolver() { + return null; + } + + @SuppressWarnings("unchecked") + @Override + public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) { + if (type == ValueMap.class) { + return (AdapterType) new ValueMapDecorator(props); + } + + return super.adaptTo(type); + } + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
