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 2014-2015 ForgeRock AS. 026 */ 027 028package org.forgerock.opendj.config; 029 030import static org.forgerock.util.Utils.closeSilently; 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 * A class for retrieving non-internationalized resource properties associated 042 * with a managed object definition. 043 * <p> 044 * Resource properties are not available for the {@link TopCfgDefn}. 045 */ 046public final class ManagedObjectDefinitionResource { 047 048 /** Mapping from definition to property tables. */ 049 private final Map<AbstractManagedObjectDefinition<?, ?>, Properties> properties = new HashMap<>(); 050 051 /** The resource name prefix. */ 052 private final String prefix; 053 054 /** 055 * Creates a new resource instance for the named profile. 056 * 057 * @param profile 058 * The name of the profile. 059 * @return Returns the resource instance for the named profile. 060 */ 061 public static ManagedObjectDefinitionResource createForProfile(String profile) { 062 return new ManagedObjectDefinitionResource("config.profiles." + profile); 063 } 064 065 /** Private constructor. */ 066 private ManagedObjectDefinitionResource(String prefix) { 067 this.prefix = prefix; 068 } 069 070 /** 071 * Get the resource value associated with the specified key. 072 * 073 * @param d 074 * The managed object definition. 075 * @param key 076 * The resource key. 077 * @return Returns the resource value associated with the specified key. 078 * @throws MissingResourceException 079 * If the key was not found. 080 * @throws UnsupportedOperationException 081 * If the provided managed object definition was the 082 * {@link TopCfgDefn}. 083 */ 084 public String getString(AbstractManagedObjectDefinition<?, ?> d, String key) { 085 if (d.isTop()) { 086 throw new UnsupportedOperationException("Profile resources are not available for the " 087 + "Top configuration definition"); 088 } 089 090 Properties p = getProperties(d); 091 String result = p.getProperty(key); 092 093 if (result == null) { 094 String baseName = prefix + "." + d.getClass().getName(); 095 String path = baseName.replace('.', '/') + ".properties"; 096 097 throw new MissingResourceException("Can't find resource " + path + ", key " + key, baseName, key); 098 } 099 100 return result; 101 } 102 103 /** 104 * Retrieve the properties table associated with a managed object, 105 * lazily loading it if necessary. 106 */ 107 private synchronized Properties getProperties(AbstractManagedObjectDefinition<?, ?> d) { 108 Properties p = properties.get(d); 109 110 if (p == null) { 111 // Load the resource file. 112 String baseName = prefix + "." + d.getClass().getName(); 113 String path = baseName.replace('.', '/') + ".properties"; 114 InputStream stream = ConfigurationFramework.getInstance().getClassLoader().getResourceAsStream(path); 115 116 if (stream == null) { 117 throw new MissingResourceException("Can't find resource " + path, baseName, ""); 118 } 119 120 final InputStream is = new BufferedInputStream(stream); 121 p = new Properties(); 122 try { 123 p.load(is); 124 } catch (IOException e) { 125 throw new MissingResourceException("Can't load resource " + path 126 + " due to IO exception: " + e.getMessage(), baseName, ""); 127 } finally { 128 closeSilently(is); 129 } 130 131 // Cache the resource. 132 properties.put(d, p); 133 } 134 135 return p; 136 } 137}