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 2015 ForgeRock AS 025 */ 026package org.opends.server.tools; 027 028import java.util.ArrayList; 029import java.util.Iterator; 030import java.util.LinkedList; 031import java.util.List; 032import java.util.regex.Matcher; 033import java.util.regex.Pattern; 034 035import org.forgerock.opendj.config.AbstractManagedObjectDefinition; 036import org.forgerock.opendj.config.DefinedDefaultBehaviorProvider; 037import org.forgerock.opendj.config.ManagedObjectDefinition; 038import org.forgerock.opendj.server.config.client.BackendCfgClient; 039import org.forgerock.opendj.server.config.meta.PluggableBackendCfgDefn; 040import org.forgerock.opendj.server.config.server.BackendCfg; 041import org.opends.guitools.controlpanel.util.Utilities; 042import org.opends.server.util.RemoveOnceNewConfigFrameworkIsUsed; 043 044/** 045 * Helper class for setup applications. It helps applications to provide a 046 * backend type choice to the user. 047 */ 048public class BackendTypeHelper 049{ 050 051 /** 052 * Filter the provided backend name by removing the backend suffix. 053 * 054 * @param dsCfgBackendName 055 * The backend name 056 * @return The backend name with the '-backend' suffix filtered out 057 */ 058 public static String filterSchemaBackendName(final String dsCfgBackendName) 059 { 060 final String cfgNameRegExp = "(.*)-backend.*"; 061 final Matcher regExpMatcher = Pattern.compile(cfgNameRegExp, Pattern.CASE_INSENSITIVE).matcher(dsCfgBackendName); 062 if (regExpMatcher.matches()) 063 { 064 return regExpMatcher.group(1); 065 } 066 067 return dsCfgBackendName; 068 } 069 070 /** Adaptor to allow backend type selection in UIs. */ 071 public static class BackendTypeUIAdapter 072 { 073 private final ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backend; 074 075 /** 076 * Create a new {@code BackendTypeUIAdapter}. 077 * 078 * @param backend 079 * The backend to adapt 080 */ 081 private BackendTypeUIAdapter(ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backend) 082 { 083 this.backend = backend; 084 } 085 086 /** 087 * Return a user friendly readable name for this backend. 088 * 089 * @return A user friendly readable name for this backend. 090 */ 091 @Override 092 public String toString() 093 { 094 return backend.getUserFriendlyName().toString(); 095 } 096 097 @Override 098 public boolean equals(Object obj) 099 { 100 return obj instanceof BackendTypeUIAdapter && ((BackendTypeUIAdapter) obj).toString().equals(toString()); 101 } 102 103 @Override 104 public int hashCode() 105 { 106 return toString().hashCode(); 107 } 108 109 /** 110 * Return the adapted backend object. 111 * 112 * @return The adapted backend object 113 */ 114 public ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> getBackend() 115 { 116 return backend; 117 } 118 119 /** 120 * Return the old configuration framework backend object. 121 * 122 * @return The old configuration framework backend object 123 */ 124 @SuppressWarnings("unchecked") 125 @RemoveOnceNewConfigFrameworkIsUsed 126 public org.opends.server.admin.ManagedObjectDefinition< 127 ? extends org.opends.server.admin.std.client.BackendCfgClient, 128 ? extends org.opends.server.admin.std.server.BackendCfg> getLegacyConfigurationFrameworkBackend() 129 { 130 Utilities.initializeLegacyConfigurationFramework(); 131 132 for (org.opends.server.admin.AbstractManagedObjectDefinition<?, ?> oldConfigBackend : 133 org.opends.server.admin.std.meta.PluggableBackendCfgDefn.getInstance().getAllChildren()) 134 { 135 if (oldConfigBackend.getName().equals(getBackend().getName())) 136 { 137 return (org.opends.server.admin.ManagedObjectDefinition< 138 ? extends org.opends.server.admin.std.client.BackendCfgClient, 139 ? extends org.opends.server.admin.std.server.BackendCfg>) oldConfigBackend; 140 } 141 } 142 throw new IllegalArgumentException("Impossible to find the equivalent backend type in old config framework: " 143 + getBackend().getName()); 144 } 145 } 146 147 private final List<ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg>> backends; 148 149 /** Creates a new backend type helper. */ 150 @SuppressWarnings("unchecked") 151 public BackendTypeHelper() 152 { 153 Utilities.initializeConfigurationFramework(); 154 155 backends = new LinkedList<>(); 156 157 for (AbstractManagedObjectDefinition<?, ?> backendType : PluggableBackendCfgDefn.getInstance().getAllChildren()) 158 { 159 // Filtering out only the non-abstract backends to avoid users attempt to create abstract ones 160 if (backendType instanceof ManagedObjectDefinition) 161 { 162 final DefinedDefaultBehaviorProvider<String> defaultBehaviorProvider = 163 (DefinedDefaultBehaviorProvider<String>) backendType.getPropertyDefinition("java-class") 164 .getDefaultBehaviorProvider(); 165 final Iterator<String> defaultBackendClassNameIterator = defaultBehaviorProvider.getDefaultValues().iterator(); 166 if (!defaultBackendClassNameIterator.hasNext()) 167 { 168 return; 169 } 170 addToBackendListIfClassExists(defaultBackendClassNameIterator.next(), 171 (ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg>) backendType); 172 } 173 } 174 } 175 176 private void addToBackendListIfClassExists(final String backendClassName, 177 final ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backendToAdd) 178 { 179 try 180 { 181 Class.forName(backendClassName); 182 backends.add(backendToAdd); 183 } 184 catch (ClassNotFoundException ignored) 185 { 186 // The backend is not supported in the running version. 187 } 188 } 189 190 191 ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> retrieveBackendTypeFromName( 192 final String backendTypeStr) 193 { 194 for (ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backendType : getBackendTypes()) 195 { 196 final String name = backendType.getName(); 197 if (backendTypeStr.equalsIgnoreCase(name) 198 || backendTypeStr.equalsIgnoreCase(filterSchemaBackendName(name))) 199 { 200 return backendType; 201 } 202 } 203 204 return null; 205 } 206 207 List<ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg>> getBackendTypes() 208 { 209 return backends; 210 } 211 212 String getPrintableBackendTypeNames() 213 { 214 String backendTypeNames = ""; 215 for (ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backend : getBackendTypes()) 216 { 217 backendTypeNames += filterSchemaBackendName(backend.getName()) + ", "; 218 } 219 220 if (backendTypeNames.isEmpty()) 221 { 222 return "Impossible to retrieve supported backend type list"; 223 } 224 225 return backendTypeNames.substring(0, backendTypeNames.length() - 2); 226 } 227 228 /** 229 * Return a list which contains all available backend type adapted for UI. 230 * 231 * @return a list which contains all available backend type adapted for UI 232 */ 233 public BackendTypeUIAdapter[] getBackendTypeUIAdaptors() 234 { 235 List<BackendTypeUIAdapter> adaptors = new ArrayList<>(); 236 for (ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backend : getBackendTypes()) 237 { 238 adaptors.add(new BackendTypeUIAdapter(backend)); 239 } 240 241 return adaptors.toArray(new BackendTypeUIAdapter[adaptors.size()]); 242 } 243 244 /** 245 * Return a BackendTypeUIAdapter which adapts the backend identified by the 246 * provided backend name. 247 * 248 * @param backendName 249 * the backend name which identifies the backend to adapt. 250 * @return a BackendTypeUIAdapter which adapts the backend identified by the 251 * provided backend name. 252 */ 253 public static BackendTypeUIAdapter getBackendTypeAdapter(String backendName) 254 { 255 ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backend = 256 new BackendTypeHelper().retrieveBackendTypeFromName(backendName); 257 return backend != null ? getBackendTypeAdapter(backend) : null; 258 } 259 260 /** 261 * Return a BackendTypeUIAdapter which adapts the provided backend. 262 * 263 * @param backend 264 * the backend type to adapt. 265 * @return a BackendTypeUIAdapter which adapts the provided backend. 266 */ 267 public static BackendTypeUIAdapter getBackendTypeAdapter( 268 ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backend) 269 { 270 return new BackendTypeUIAdapter(backend); 271 } 272 273}