PageRenderTime 60ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/extensions/serviceusermapper/src/main/java/org/apache/sling/serviceusermapping/impl/ServiceUserMapperImpl.java

https://github.com/Gundalf72/sling
Java | 178 lines | 127 code | 26 blank | 25 comment | 16 complexity | dd2a6c4cf268a1c736b782b1049c9921 MD5 | raw file
Possible License(s): Apache-2.0, EPL-1.0, MPL-2.0-no-copyleft-exception, MPL-2.0, BSD-3-Clause, CPL-1.0
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. package org.apache.sling.serviceusermapping.impl;
  20. import java.util.ArrayList;
  21. import java.util.Collections;
  22. import java.util.HashMap;
  23. import java.util.List;
  24. import java.util.Map;
  25. import org.apache.felix.scr.annotations.Activate;
  26. import org.apache.felix.scr.annotations.Component;
  27. import org.apache.felix.scr.annotations.Modified;
  28. import org.apache.felix.scr.annotations.Property;
  29. import org.apache.felix.scr.annotations.PropertyUnbounded;
  30. import org.apache.felix.scr.annotations.Reference;
  31. import org.apache.felix.scr.annotations.ReferenceCardinality;
  32. import org.apache.felix.scr.annotations.ReferencePolicy;
  33. import org.apache.felix.scr.annotations.Service;
  34. import org.apache.sling.commons.osgi.PropertiesUtil;
  35. import org.apache.sling.serviceusermapping.ServiceUserMapper;
  36. import org.osgi.framework.Bundle;
  37. import org.osgi.framework.Constants;
  38. import org.slf4j.Logger;
  39. import org.slf4j.LoggerFactory;
  40. @Component(
  41. metatype = true,
  42. label = "Apache Sling Service User Mapper Service",
  43. description = "Configuration for the service mapping service names to names of users.")
  44. @Service(value=ServiceUserMapper.class)
  45. @Reference(name="amendment",
  46. referenceInterface=MappingConfigAmendment.class,
  47. cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
  48. policy=ReferencePolicy.DYNAMIC,
  49. updated="update")
  50. public class ServiceUserMapperImpl implements ServiceUserMapper {
  51. @Property(
  52. label = "Service Mappings",
  53. description = "Provides mappings from service name to user names. "
  54. + "Each entry is of the form 'bundleId [ \":\" subServiceName ] \"=\" userName' "
  55. + "where bundleId and subServiceName identify the service and userName "
  56. + "defines the name of the user to provide to the service. Invalid entries are logged and ignored.",
  57. unbounded = PropertyUnbounded.ARRAY)
  58. private static final String PROP_SERVICE2USER_MAPPING = "user.mapping";
  59. private static final String[] PROP_SERVICE2USER_MAPPING_DEFAULT = {};
  60. private static final String PROP_DEFAULT_USER = "user.default";
  61. @Property(
  62. name = PROP_DEFAULT_USER,
  63. label = "Default User",
  64. description = "The name of the user to use as the default if no service mapping"
  65. + "applies. If this property is missing or empty no default user is defined.")
  66. private static final String PROP_DEFAULT_USER_DEFAULT = null;
  67. /** default log */
  68. private final Logger log = LoggerFactory.getLogger(getClass());
  69. private Mapping[] globalServiceUserMappings = new Mapping[0];
  70. private String defaultUser;
  71. private Map<Long, MappingConfigAmendment> amendments = new HashMap<Long, MappingConfigAmendment>();
  72. private Mapping[] activeMappings = new Mapping[0];
  73. @Activate
  74. @Modified
  75. void configure(final Map<String, Object> config) {
  76. final String[] props = PropertiesUtil.toStringArray(config.get(PROP_SERVICE2USER_MAPPING),
  77. PROP_SERVICE2USER_MAPPING_DEFAULT);
  78. final ArrayList<Mapping> mappings = new ArrayList<Mapping>(props.length);
  79. for (final String prop : props) {
  80. if (prop != null && prop.trim().length() > 0 ) {
  81. try {
  82. final Mapping mapping = new Mapping(prop.trim());
  83. mappings.add(mapping);
  84. } catch (final IllegalArgumentException iae) {
  85. log.info("configure: Ignoring '{}': {}", prop, iae.getMessage());
  86. }
  87. }
  88. }
  89. this.globalServiceUserMappings = mappings.toArray(new Mapping[mappings.size()]);
  90. this.defaultUser = PropertiesUtil.toString(config.get(PROP_DEFAULT_USER), PROP_DEFAULT_USER_DEFAULT);
  91. synchronized ( this.amendments ) {
  92. this.updateMappings();
  93. }
  94. }
  95. /**
  96. * @see org.apache.sling.serviceusermapping.ServiceUserMapper#getServiceUserID(org.osgi.framework.Bundle, java.lang.String)
  97. */
  98. public String getServiceUserID(final Bundle bundle, final String subServiceName) {
  99. final String serviceName = bundle.getSymbolicName();
  100. // try with serviceInfo first
  101. for (Mapping mapping : this.activeMappings) {
  102. final String user = mapping.map(serviceName, subServiceName);
  103. if (user != null) {
  104. return user;
  105. }
  106. }
  107. // second round without serviceInfo
  108. for (Mapping mapping : this.activeMappings) {
  109. final String user = mapping.map(serviceName, null);
  110. if (user != null) {
  111. return user;
  112. }
  113. }
  114. // finally, fall back to default user
  115. return this.defaultUser;
  116. }
  117. protected void bindAmendment(final MappingConfigAmendment amendment, final Map<String, Object> props) {
  118. final Long key = (Long) props.get(Constants.SERVICE_ID);
  119. synchronized ( this.amendments ) {
  120. amendments.put(key, amendment);
  121. this.updateMappings();
  122. }
  123. }
  124. protected void unbindAmendment(final MappingConfigAmendment amendment, final Map<String, Object> props) {
  125. final Long key = (Long) props.get(Constants.SERVICE_ID);
  126. synchronized ( this.amendments ) {
  127. if ( amendments.remove(key) != null ) {
  128. this.updateMappings();
  129. };
  130. }
  131. }
  132. protected void updateAmendment(final MappingConfigAmendment amendment, final Map<String, Object> props) {
  133. this.bindAmendment(amendment, props);
  134. }
  135. protected void updateMappings() {
  136. final List<MappingConfigAmendment> sortedMappings = new ArrayList<MappingConfigAmendment>();
  137. for(final MappingConfigAmendment amendment : this.amendments.values() ) {
  138. sortedMappings.add(amendment);
  139. }
  140. Collections.sort(sortedMappings);
  141. final List<Mapping> mappings = new ArrayList<Mapping>();
  142. for(final Mapping m : this.globalServiceUserMappings) {
  143. mappings.add(m);
  144. }
  145. for(final MappingConfigAmendment mca : sortedMappings) {
  146. for(final Mapping m : mca.getServiceUserMappings()) {
  147. mappings.add(m);
  148. }
  149. }
  150. activeMappings = mappings.toArray(new Mapping[mappings.size()]);
  151. }
  152. }