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