001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: TemplateManager.java,v 1.4 2008/06/25 05:41:46 qcheng Exp $ 026 * 027 */ 028 029package com.iplanet.ums; 030 031import java.util.ArrayList; 032import java.util.Collections; 033import java.util.Enumeration; 034import java.util.Set; 035import java.util.Vector; 036 037import com.iplanet.services.ldap.Attr; 038import com.iplanet.services.ldap.AttrSet; 039import com.iplanet.services.util.I18n; 040 041/** 042 * The class manages a set of templates. The set of templates can be used to 043 * define what attributes to use when creating an object, or what attributes to 044 * retrieve for a particular object. 045 * 046 * <p> 047 * Example: 048 * <p> 049 * 050 * <pre> 051 * TemplateManager mgr = TemplateManager.getTemplateManager(); 052 * 053 * Guid guid = new Guid("o=vortex.com"); 054 * 055 * CreationTemplate t1 = mgr.getCreationTemplate("BasicUser", guid, 056 * TemplateManager.SCOPE_ANCESTORS); 057 * 058 * CreationTemplate t2 = mgr.getCreationTemplate(User.class, guid, 059 * TemplateManager.SCOPE_ANCESTORS); 060 * 061 * SearchTemplate t3 = mgr.getSearchTemplate("BasicUserSearch", guid, 062 * TemplateManager.SCOPE_ANCESTORS); 063 * </pre> 064 * 065 * @see com.iplanet.ums.Template 066 * @see com.iplanet.ums.CreationTemplate 067 * @see com.iplanet.ums.SearchTemplate 068 * @supported.api 069 */ 070public class TemplateManager implements java.io.Serializable { 071 072 /** 073 * Search scope for determining how to get the configuration data. This will 074 * get the configuration data at the organization level specified. 075 * 076 * @supported.api 077 */ 078 public static final int SCOPE_ORG = 0; 079 080 /** 081 * Search scope for determining how to get the configuration data. This will 082 * get the configuration data from the nearest ancestor containing the 083 * configuration data. 084 * 085 * @supported.api 086 */ 087 public static final int SCOPE_ANCESTORS = 1; 088 089 /** 090 * Search scope for determining how to get the configuration data. This will 091 * get the configuration data at the organization level, and if not found, 092 * then at the root level. 093 * 094 * @supported.api 095 */ 096 public static final int SCOPE_TOP = 2; 097 098 private static final String TEMPLATE_NAME = "name"; 099 100 private static final String TEMPLATE_JAVACLASS = "javaclass"; 101 102 private static final String TEMPLATE_OPTIONAL = "optional"; 103 104 private static final String TEMPLATE_REQUIRED = "required"; 105 106 private static final String TEMPLATE_VALIDATED = "validated"; 107 108 private static final String TEMPLATE_NAMINGATTRIBUTE = "namingattribute"; 109 110 private static final String TEMPLATE_SEARCH_FILTER = "searchfilter"; 111 112 private static final String SCHEMA2_SEARCH_FILTER = 113 "inetDomainSearchFilter"; 114 115 private static final String TEMPLATE_ATTRS = "attrs"; 116 117 private static I18n i18n = I18n.getInstance(IUMSConstants.UMS_PKG); 118 119 /** 120 * Default constructor that registers a default class resolver and accesses 121 * template configuration information. 122 * 123 * @throws UMSException 124 * if an exception occurs registering the resolver or accessing 125 * configuration data. 126 */ 127 protected TemplateManager() throws UMSException { 128 // Register com.iplanet.ums.DefaultClassResolver to resolve 129 // a set of attributes to a Java class. 130 addClassResolver(new DefaultClassResolver()); 131 // Register com.iplanet.ums.GroupResolver that can distinguish 132 // between regular dynamic groups and assignable ones 133 addClassResolver(new GroupResolver()); 134 try { 135 m_configManager = ConfigManagerUMS.getConfigManager(); 136 } catch (ConfigManagerException e) { 137 throw new UMSException(e.getMessage()); 138 } 139 } 140 141 /** 142 * Clients can only obtain a reference through this method. 143 * 144 * @return the one and only instance 145 * @throws UMSException 146 * if an exception occurs while getting an instance of a 147 * template manager. 148 * 149 * @supported.api 150 */ 151 public static synchronized TemplateManager getTemplateManager() 152 throws UMSException { 153 if (m_mgr == null) { 154 m_mgr = new TemplateManager(); 155 } 156 return m_mgr; 157 } 158 159 /** 160 * Registers a class that can resolve a set of attributes to a Java class. 161 * The last class registered is the first to be called in the resolution 162 * chain. 163 * 164 * @param resolver 165 * a class that can produce a Java class instance from an ID and 166 * a set of attributes 167 */ 168 public void addClassResolver(IClassResolver resolver) { 169 m_resolvers.addElement(resolver); 170 } 171 172 /** 173 * Unregisters a class that can resolve a set of attributes to a Java class. 174 * 175 * @param resolver 176 * A class that can produce a Java class instance from an ID and 177 * a set of attributes 178 */ 179 public void removeClassResolver(IClassResolver resolver) { 180 m_resolvers.remove(resolver); 181 } 182 183 /** 184 * Given a class, gets the default creation template for the object. This 185 * will traverse the tree all the way to the root until the CreationTemplate 186 * is found. 187 * 188 * @param cls Class (instance of) to be queried for the template. 189 * @param orgGuid GUID of the Organization where the config data is stored. 190 * @return Creation template for the class or <code>null</code> if the 191 * class is not known or no template is registered for the class. 192 * @throws UMSException if an exception occurs while getting the creation 193 * template. 194 * @supported.api 195 */ 196 public CreationTemplate getCreationTemplate(Class cls, Guid orgGuid) 197 throws UMSException { 198 199 return getCreationTemplate(cls, orgGuid, SCOPE_ANCESTORS); 200 } 201 202 /** 203 * Returns default creation template of a given class. 204 * 205 * @param cls Class (instance of) to be queried for the template. 206 * @param orgGuid GUID of the Organization where the config data is stored. 207 * @param scope Search scope for determining how to get the configuration 208 * data 209 * @return Creation template for the class or <code>null</code> if the 210 * class is not known or no template is registered for the class 211 * @throws UMSException if error occurs while getting the creation template. 212 * @supported.api 213 */ 214 public CreationTemplate getCreationTemplate(Class cls, Guid orgGuid, 215 int scope) throws UMSException { 216 if (cls == null) { 217 String msg = i18n.getString(IUMSConstants.BAD_CLASS); 218 throw new IllegalArgumentException(msg); 219 } 220 221 AttrSet attrSet = null; 222 try { 223 attrSet = m_configManager.getCreationTemplateForClass(orgGuid, cls 224 .getName(), scope); 225 } catch (ConfigManagerException e) { 226 throw new UMSException(e.getMessage()); 227 } 228 if (attrSet == null) { 229 return null; 230 } 231 232 return toCreationTemplate(attrSet); 233 } 234 235 /** 236 * Returns a template from a supplied template name. This will traverse the 237 * tree all the way to the root until the CreationTemplate is found. 238 * 239 * @param name Name of template. 240 * @param orgGuid GUID of the Organization where the config data is stored. 241 * @return CreationTemplate matching the supplied name, or <code>null</code> 242 * if there is no matching template 243 * @throws UMSException if error occurs while getting the creation template. 244 * @supported.api 245 */ 246 public CreationTemplate getCreationTemplate(String name, Guid orgGuid) 247 throws UMSException { 248 return getCreationTemplate(name, orgGuid, SCOPE_ANCESTORS); 249 } 250 251 /** 252 * Returns a template from a supplied template name. 253 * 254 * @param name Name of template. 255 * @param orgGuid GUID of the Organization where the config data is stored. 256 * @param scope Search scope for determining how to get the configuration 257 * data. 258 * @return CreationTemplate matching the supplied name, or <code>null</code> 259 * if there is no matching template 260 * @throws UMSException if an exception occurs while getting the creation 261 * template. 262 * @supported.api 263 */ 264 public CreationTemplate getCreationTemplate(String name, Guid orgGuid, 265 int scope) throws UMSException { 266 if (name == null) { 267 String msg = i18n.getString(IUMSConstants.MISSING_TEMPL_NAME); 268 throw new IllegalArgumentException(msg); 269 } 270 271 AttrSet attrSet = null; 272 273 try { 274 attrSet = m_configManager.getCreationTemplate(orgGuid, name, scope); 275 } catch (ConfigManagerException e) { 276 throw new UMSException(e.getMessage()); 277 } 278 279 if (attrSet == null) { 280 return null; 281 } 282 283 return toCreationTemplate(attrSet); 284 } 285 286 /** 287 * Returns a template from a supplied template name. This will traverse the 288 * tree all the way to the root till the SearchTemplate is found. 289 * 290 * @param name Name of template. 291 * @param orgGuid GUID of the Organization where the config data is stored 292 * @return SearchTemplate matching the supplied name, or <code>null</code> 293 * if there is no matching template 294 * @throws UMSException if error occurs while getting the search template. 295 * @supported.api 296 */ 297 public SearchTemplate getSearchTemplate(String name, Guid orgGuid) 298 throws UMSException { 299 return getSearchTemplate(name, orgGuid, SCOPE_ANCESTORS); 300 } 301 302 /** 303 * Returns a template from a supplied template name. 304 * 305 * @param name Name of Template. 306 * @param orgGuid GUID of the Organization where the config data is stored. 307 * @param scope Search scope for determining how to get the configuration 308 * data. 309 * @return SearchTemplate matching the supplied name, or <code>null</code> 310 * if there is no matching template. 311 * @throws UMSException if an exception occurs while getting the search 312 * template. 313 * @supported.api 314 */ 315 public SearchTemplate getSearchTemplate( 316 String name, 317 Guid orgGuid, 318 int scope 319 ) throws UMSException { 320 if (name == null) { 321 String msg = i18n.getString(IUMSConstants.MISSING_TEMPL_NAME); 322 323 throw new IllegalArgumentException(msg); 324 } 325 AttrSet attrSet = null; 326 try { 327 attrSet = m_configManager.getSearchTemplate(orgGuid, name, scope); 328 } catch (ConfigManagerException e) { 329 throw new UMSException(e.getMessage()); 330 } 331 if (attrSet == null) { 332 return null; 333 } 334 return toSearchTemplate(attrSet); 335 } 336 337 /** 338 * Returns a set of known creation templates. 339 * 340 * @param orgGuid GUID of the Organization where the config data is stored. 341 * @return Names of known creation templates 342 * @throws UMSException if an exception occurs. 343 * @supported.api 344 */ 345 public Set getCreationTemplateNames(Guid orgGuid) throws UMSException { 346 Set names = null; 347 try { 348 names = m_configManager.getCreationTemplateNames(orgGuid); 349 } catch (ConfigManagerException e) { 350 throw new UMSException(e.getMessage()); 351 } 352 return (names != null) ? names : Collections.EMPTY_SET; 353 } 354 355 /** 356 * Returns a set of known search templates. 357 * 358 * @param orgGuid GUID of the Organization where the config data is stored. 359 * @return Names of known search templates. 360 * @throws UMSException if an exception occurs. 361 * @supported.api 362 */ 363 public Set getSearchTemplateNames(Guid orgGuid) throws UMSException { 364 Set names = null; 365 try { 366 names = m_configManager.getSearchTemplateNames(orgGuid); 367 } catch (ConfigManagerException e) { 368 throw new UMSException(e.getMessage()); 369 } 370 return (names != null) ? names : Collections.EMPTY_SET; 371 } 372 373 /** 374 * Replaces an existing CreationTemplate with the one specified. 375 * 376 * @param template 377 * CreationTemplate to be modified 378 * @param orgGuid 379 * the guid of the Organization where the config data is stored 380 * @throws UMSException 381 * if an exception occurs 382 */ 383 public void replaceCreationTemplate(CreationTemplate template, Guid orgGuid) 384 throws UMSException { 385 if (template == null) { 386 return; 387 } 388 389 String templateName = template.getName(); 390 if (templateName == null) { 391 String msg = i18n.getString(IUMSConstants.MISSING_TEMPL_NAME); 392 393 throw new IllegalArgumentException(msg); 394 } 395 396 AttrSet attrSet = toAttrSet(template); 397 try { 398 m_configManager.replaceCreationTemplate(orgGuid, templateName, 399 attrSet); 400 } catch (ConfigManagerException e) { 401 throw new UMSException(e.getMessage()); 402 } 403 } 404 405 private AttrSet toAttrSet(CreationTemplate t) { 406 AttrSet attrSet = new AttrSet(); 407 408 attrSet.add(new Attr(TemplateManager.TEMPLATE_NAME, t.getName())); 409 410 attrSet.add(new Attr(TemplateManager.TEMPLATE_NAMINGATTRIBUTE, t 411 .getNamingAttribute())); 412 413 ArrayList classes = t.getCreationClasses(); 414 String[] classNames = new String[classes.size()]; 415 for (int i = 0; i < classes.size(); i++) { 416 Class cls = (Class) classes.get(i); 417 classNames[i] = cls.getName(); 418 } 419 attrSet.add(new Attr(TemplateManager.TEMPLATE_JAVACLASS, classNames)); 420 421 Attr required = encodeAttrSet(TemplateManager.TEMPLATE_REQUIRED, t 422 .getRequiredAttributeSet(), "="); 423 if (required != null) { 424 attrSet.add(required); 425 } 426 427 Attr optional = encodeAttrSet(TemplateManager.TEMPLATE_OPTIONAL, t 428 .getOptionalAttributeSet(), "="); 429 if (optional != null) { 430 attrSet.add(optional); 431 } 432 433 Attr validated = encodeAttrSet(TemplateManager.TEMPLATE_VALIDATED, t 434 .getValidation(), "="); 435 if (validated != null) { 436 attrSet.add(validated); 437 } 438 439 return attrSet; 440 } 441 442 /** 443 * Gets the Java class given the id and attribute set of an entry. The Java 444 * class is inferred from the default CreationTemplate(s) registered with 445 * this template manager. A different inference rule could be implemented by 446 * subclassing the TemplateManager and overriding this method. This 447 * implementation figures out the Java class for the entry. 448 * 449 * @param guid 450 * Guid of the entry 451 * @param attrSet 452 * Attribute set of the entry 453 * @return Java Class that maps to the list of LDAP object classes 454 * @exception UMSException 455 * if the template manager has not been properly initialized 456 */ 457 Class getJavaClassForEntry(String id, AttrSet attrSet) throws UMSException { 458 Class javaClass = null; 459 int i = m_resolvers.size() - 1; 460 while ((javaClass == null) && (i >= 0)) { 461 IClassResolver resolver = (IClassResolver) m_resolvers.elementAt(i); 462 javaClass = resolver.resolve(id, attrSet); 463 i--; 464 } 465 466 if (javaClass == null) { 467 javaClass = PersistentObject.class; 468 } 469 470 return javaClass; 471 } 472 473 /** 474 * Reads in a attribute set and converts name-value pairs to a 475 * CreationTemplate object. 476 * 477 * @param t 478 * attribute set contains template values 479 * @return CreationTemplate object based on the name-value pairs 480 */ 481 private CreationTemplate toCreationTemplate(AttrSet t) { 482 Attr nameAttr = t.getAttribute(TEMPLATE_NAME); 483 String name = null; 484 if (nameAttr != null) { 485 name = nameAttr.getValue(); 486 } 487 488 Attr namingAttr = t.getAttribute(TEMPLATE_NAMINGATTRIBUTE); 489 String namingAttribute = null; 490 if (namingAttr != null) { 491 namingAttribute = namingAttr.getValue(); 492 } 493 494 Attr classAttr = t.getAttribute(TEMPLATE_JAVACLASS); 495 String[] classNames = null; 496 if (classAttr != null) { 497 classNames = classAttr.getStringValues(); 498 } 499 500 AttrSet required = decodeAttr(t.getAttribute(TEMPLATE_REQUIRED), "="); 501 AttrSet optional = decodeAttr(t.getAttribute(TEMPLATE_OPTIONAL), "="); 502 AttrSet validated = decodeAttr(t.getAttribute(TEMPLATE_VALIDATED), "="); 503 504 CreationTemplate template = new CreationTemplate(); 505 ArrayList classes = new ArrayList(); 506 507 try { 508 if (classNames != null) { 509 for (int i = 0; i < classNames.length; i++) { 510 Class cls = Class.forName(classNames[i]); 511 classes.add(cls); 512 } 513 } 514 template = new CreationTemplate(name, required, optional, classes); 515 516 } catch (ClassNotFoundException e) { 517 template = new CreationTemplate(name, required, optional); 518 } 519 520 if (validated != null) { 521 template.setValidation(validated); 522 } 523 524 if (namingAttribute != null) { 525 template.setNamingAttribute(namingAttribute); 526 } 527 528 return template; 529 } 530 531 /** 532 * Reads in a attribute set and converts name-value pairs to a 533 * SearchTemplate object. 534 * 535 * @param t 536 * attribute set contains template values 537 * @return SearchTemplate object based on the name-value pairs 538 */ 539 private SearchTemplate toSearchTemplate(AttrSet t) { 540 Attr nameAttr = t.getAttribute(TEMPLATE_NAME); 541 String name = null; 542 if (nameAttr != null) { 543 name = nameAttr.getValue(); 544 } 545 546 Attr filterAttr = t.getAttribute(SCHEMA2_SEARCH_FILTER); 547 if (filterAttr == null) { 548 filterAttr = t.getAttribute(TEMPLATE_SEARCH_FILTER); 549 } 550 String filter = null; 551 if (filterAttr != null) { 552 filter = filterAttr.getValue(); 553 } 554 555 AttrSet attrSet = decodeAttr(t.getAttribute(TEMPLATE_ATTRS), "="); 556 557 SearchTemplate template = new SearchTemplate(); 558 559 template = new SearchTemplate(name, attrSet, filter); 560 561 return template; 562 } 563 564 /** 565 * Decode single attribute with multiple values into an AttrSet. For 566 * example: 567 * 568 * <pre> 569 * Attribute: 570 * required: objectclass=top 571 * required: objectclass=groupofuniquenames 572 * required: cn 573 * required: sn 574 * 575 * Attribute Set: 576 * objectclass: top 577 * objectclass: groupofuniquenames 578 * cn: 579 * sn: 580 * </pre> 581 * 582 * @param attr 583 * Attribute to be decoded from 584 * @param delimiter 585 * Delimiter used in the encoding 586 * @return Decoded attribute set 587 */ 588 private AttrSet decodeAttr(Attr attr, String delimiter) { 589 590 if (attr == null) 591 return null; 592 593 String[] values = attr.getStringValues(); 594 AttrSet attrSet = new AttrSet(); 595 596 for (int i = 0, size = attr.size(); i < size; i++) { 597 String value = values[i]; 598 String attrName = null; 599 String attrValue = null; 600 601 int index = value.indexOf('='); 602 if (index < 0) { 603 attrName = value; 604 } else { 605 attrName = value.substring(0, index); 606 attrValue = value.substring(index + 1, value.length()); 607 } 608 609 if (attrValue != null && attrValue.length() != 0) { 610 attrSet.add(new Attr(attrName, attrValue)); 611 } else { 612 attrSet.add(new Attr(attrName)); 613 } 614 615 } 616 return attrSet; 617 } 618 619 /** 620 * Encode an attrSet in a single attribute with multiple values using the 621 * given attribute name and the values (tag,value) found in the given 622 * attribute set. For example: 623 * 624 * <pre> 625 * Attribute: 626 * required: objectclass=top 627 * required: objectclass=groupofuniquenames 628 * required: cn 629 * required: sn 630 * 631 * Attribute Set: 632 * objectclass: top 633 * objectclass: groupofuniquenames 634 * cn: 635 * sn: 636 * </pre> 637 * 638 * @param attrName 639 * Name of the encoded attribute. 640 * @param attrSet 641 * Attribute set to be encoded in a single attribut.e 642 * @param delimiter 643 * String token used as delimiter for the encoding. 644 * @return Encoded attribute or null object if attrSet is empty. 645 */ 646 private Attr encodeAttrSet(String attrName, AttrSet attrSet, 647 String delimiter) { 648 if (attrSet == null || attrSet.size() == 0) { 649 return null; 650 } 651 652 Enumeration attrEnum = attrSet.getAttributes(); 653 Attr encodedAttr = new Attr(attrName); 654 655 while (attrEnum.hasMoreElements()) { 656 Attr a = (Attr) attrEnum.nextElement(); 657 String[] values = a.getStringValues(); 658 String[] encodedValues = new String[values.length]; 659 660 if (values.length == 0) { 661 encodedAttr.addValue(a.getName()); 662 } else { 663 for (int i = 0; i < values.length; i++) { 664 encodedValues[i] = a.getName() + delimiter + values[i]; 665 } 666 encodedAttr.addValues(encodedValues); 667 } 668 } 669 670 return encodedAttr; 671 } 672 673 private Vector m_resolvers = new Vector(); 674 675 private ConfigManagerUMS m_configManager = null; 676 677 // Single instance of TemplateManager 678 private static TemplateManager m_mgr; 679 680}
Copyright © 2010-2017, ForgeRock All Rights Reserved.