001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008 Sun Microsystems, Inc.
025 *      Portions Copyright 2015 ForgeRock AS.
026 */
027
028package org.opends.server.admin;
029
030
031
032import java.io.BufferedInputStream;
033import java.io.IOException;
034import java.io.InputStream;
035import java.util.HashMap;
036import java.util.Map;
037import java.util.MissingResourceException;
038import java.util.Properties;
039
040
041
042/**
043 * A class for retrieving non-internationalized resource properties
044 * associated with a managed object definition.
045 * <p>
046 * Resource properties are not available for the {@link TopCfgDefn}.
047 */
048public final class ManagedObjectDefinitionResource {
049
050  /** Mapping from definition to property tables. */
051  private final Map<AbstractManagedObjectDefinition<?, ?>, Properties> properties = new HashMap<>();
052  /** The resource name prefix. */
053  private final String prefix;
054
055  /**
056   * Creates a new resource instance for the named profile.
057   *
058   * @param profile
059   *          The name of the profile.
060   * @return Returns the resource instance for the named profile.
061   */
062  public static ManagedObjectDefinitionResource createForProfile(String profile) {
063    return new ManagedObjectDefinitionResource("admin.profiles." + profile);
064  }
065
066  /** Private constructor. */
067  private ManagedObjectDefinitionResource(String prefix) {
068    this.prefix = prefix;
069  }
070
071  /**
072   * Get the resource value associated with the specified key.
073   *
074   * @param d
075   *          The managed object definition.
076   * @param key
077   *          The resource key.
078   * @return Returns the resource value associated with the specified
079   *         key.
080   * @throws MissingResourceException
081   *           If the key was not found.
082   * @throws UnsupportedOperationException
083   *           If the provided managed object definition was the
084   *           {@link TopCfgDefn}.
085   */
086  public String getString(AbstractManagedObjectDefinition<?, ?> d, String key)
087      throws MissingResourceException, UnsupportedOperationException {
088    if (d.isTop()) {
089      throw new UnsupportedOperationException(
090          "Profile resources are not available for the "
091              + "Top configuration definition");
092    }
093
094    Properties p = getProperties(d);
095    String result = p.getProperty(key);
096
097    if (result == null) {
098      String baseName = prefix + "." + d.getClass().getName();
099      String path = baseName.replace('.', '/') + ".properties";
100
101      throw new MissingResourceException("Can't find resource "
102          + path + ", key " + key, baseName, key);
103    }
104
105    return result;
106  }
107
108
109
110  /**
111   * Retrieve the properties table associated with a managed object,
112   * lazily loading it if necessary.
113   */
114  private synchronized Properties getProperties(
115      AbstractManagedObjectDefinition<?, ?> d)
116      throws MissingResourceException {
117    Properties p = properties.get(d);
118
119    if (p == null) {
120      // Load the resource file.
121      String baseName = prefix + "." + d.getClass().getName();
122      String path = baseName.replace('.', '/') + ".properties";
123      InputStream stream = ClassLoaderProvider.getInstance()
124          .getClassLoader().getResourceAsStream(path);
125
126      if (stream == null) {
127        throw new MissingResourceException("Can't find resource "
128            + path, baseName, "");
129      }
130
131      p = new Properties();
132      try {
133        p.load(new BufferedInputStream(stream));
134      } catch (IOException e) {
135        throw new MissingResourceException("Can't load resource "
136            + path + " due to IO exception: " + e.getMessage(),
137            baseName, "");
138      }
139
140      // Cache the resource.
141      properties.put(d, p);
142    }
143
144    return p;
145  }
146}