true if an attribute value must be obfuscated because
* it contains sensitive information (like passwords) and false
* otherwise.
* @param attrName the attribute name.
* @param schema the schema of the server.
* @return true if an attribute value must be obfuscated because
* it contains sensitive information (like passwords) and false
* otherwise.
*/
public static boolean mustObfuscate(String attrName, Schema schema)
{
if (schema != null)
{
return hasPasswordSyntax(attrName, schema);
}
for (String attr : attrsToObfuscate)
{
if (attr.equalsIgnoreCase(attrName))
{
return true;
}
}
return false;
}
/**
* Derives a color by adding the specified offsets to the base color's
* hue, saturation, and brightness values. The resulting hue, saturation,
* and brightness values will be contrained to be between 0 and 1.
* @param base the color to which the HSV offsets will be added
* @param dH the offset for hue
* @param dS the offset for saturation
* @param dB the offset for brightness
* @return Color with modified HSV values
*/
public static Color deriveColorHSB(Color base, float dH, float dS, float dB)
{
float hsb[] = Color.RGBtoHSB(
base.getRed(), base.getGreen(), base.getBlue(), null);
hsb[0] += dH;
hsb[1] += dS;
hsb[2] += dB;
return Color.getHSBColor(
hsb[0] < 0? 0 : (hsb[0] > 1? 1 : hsb[0]),
hsb[1] < 0? 0 : (hsb[1] > 1? 1 : hsb[1]),
hsb[2] < 0? 0 : (hsb[2] > 1? 1 : hsb[2]));
}
/**
* Displays an error dialog that contains a set of error messages.
* @param parentComponent the parent component relative to which the dialog
* will be displayed.
* @param errors the set of error messages that the dialog must display.
*/
public static void displayErrorDialog(Component parentComponent,
Collectiontrue if the user
* accepts the message and false otherwise.
* @param parentComponent the parent component relative to which the dialog
* will be displayed.
* @param title the title of the dialog.
* @param msg the message to be displayed.
* @return true if the user accepts the message and
* false otherwise.
*
*/
public static boolean displayConfirmationDialog(Component parentComponent,
LocalizableMessage title, LocalizableMessage msg)
{
String plainText = msg.toString().replaceAll("null if the path was invalid.
* @param path the path of the image.
* @param loader the class loader to use to load the image. If
* null this class class loader will be used.
* @return an ImageIcon or null if the path was invalid.
*/
public static ImageIcon createImageIcon(String path, ClassLoader loader) {
if (loader == null)
{
loader = ControlPanel.class.getClassLoader();
}
java.net.URL imgURL = loader.getResource(path);
return imgURL != null ? new ImageIcon(imgURL) : null;
}
/**
* Returns an ImageIcon or null if the path was invalid.
* @param path the path of the image.
* @return an ImageIcon or null if the path was invalid.
*/
public static ImageIcon createImageIcon(String path) {
return createImageIcon(path, null);
}
/**
* Creates an image icon using an array of bytes that contain the image and
* specifying the maximum height of the image.
* @param bytes the byte array.
* @param maxHeight the maximum height of the image.
* @param description the description of the image.
* @param useFast whether a fast algorithm must be used to transform the image
* or an algorithm with a better result.
* @return an image icon using an array of bytes that contain the image and
* specifying the maximum height of the image.
*/
public static ImageIcon createImageIcon(byte[] bytes, int maxHeight,
LocalizableMessage description, boolean useFast)
{
ImageIcon icon = new ImageIcon(bytes, description.toString());
if (maxHeight > icon.getIconHeight() || icon.getIconHeight() <= 0)
{
return icon;
}
int newHeight = maxHeight;
int newWidth = (newHeight * icon.getIconWidth()) / icon.getIconHeight();
int algo = useFast ? Image.SCALE_FAST : Image.SCALE_SMOOTH;
Image scaledImage = icon.getImage().getScaledInstance(newWidth, newHeight, algo);
return new ImageIcon(scaledImage);
}
/**
* Updates the preferred size of an editor pane.
* @param pane the panel to be updated.
* @param nCols the number of columns that the panel must have.
* @param plainText the text to be displayed (plain text).
* @param font the font to be used.
* @param applyBackground whether an error/warning background must be applied
* to the text or not.
*/
public static void updatePreferredSize(JEditorPane pane, int nCols,
String plainText, Font font, boolean applyBackground)
{
String wrappedText = wrapText(plainText, nCols);
wrappedText = wrappedText.replaceAll(ServerConstants.EOL, "".equalsIgnoreCase(tag) || "
".equalsIgnoreCase(tag); } /** * Center the component location based on its preferred size. The code * considers the particular case of 2 screens and puts the component on the * center of the left screen * * @param comp the component to be centered. */ public static void centerOnScreen(Component comp) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int width = comp.getPreferredSize().width; int height = comp.getPreferredSize().height; boolean multipleScreen = screenSize.width / screenSize.height >= 2; if (multipleScreen) { comp.setLocation((screenSize.width / 4) - (width / 2), (screenSize.height - height) / 2); } else { comp.setLocation((screenSize.width - width) / 2, (screenSize.height - height) / 2); } } /** * Center the component location of the ref component. * * @param comp the component to be centered. * @param ref the component to be used as reference. * */ public static void centerGoldenMean(Window comp, Component ref) { comp.setLocationRelativeTo(ref); // Apply the golden mean if (ref != null && ref.isVisible()) { int refY = ref.getY(); int refHeight = ref.getHeight(); int compHeight = comp.getPreferredSize().height; int newY = refY + (int) (refHeight * 0.3819 - compHeight * 0.5); // Check that the new window will be fully visible Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); if (newY > 0 && screenSize.height > newY + compHeight) { comp.setLocation(comp.getX(), newY); } } } /** * Returns the parent frame of a component.null if this
* component is not contained in any frame.
* @param comp the component.
* @return the parent frame of a component. null if this
* component is not contained in any frame.
*/
public static JFrame getFrame(Component comp)
{
Component parent = comp;
while (parent != null && !(parent instanceof JFrame))
{
parent = parent.getParent();
}
return parent != null ? (JFrame) parent : null;
}
/**
* Returns the parent dialog of a component. null if this
* component is not contained in any dialog.
* @param comp the component.
* @return the parent dialog of a component. null if this
* component is not contained in any dialog.
*/
public static Window getParentDialog(Component comp)
{
Component parent = comp;
while (parent != null)
{
if (parent instanceof JDialog || parent instanceof JFrame)
{
return (Window)parent;
}
parent = parent.getParent();
}
return null;
}
/**
* Unescapes UTF-8 text and generates a String from it.
* @param v the string in UTF-8 format.
* @return the string with unescaped characters.
*/
public static String unescapeUtf8(String v)
{
try
{
byte[] stringBytes = v.getBytes("UTF-8");
byte[] decodedBytes = new byte[stringBytes.length];
int pos = 0;
for (int i = 0; i < stringBytes.length; i++)
{
if (stringBytes[i] == '\\'
&& i + 2 < stringBytes.length
&& StaticUtils.isHexDigit(stringBytes[i+1])
&& StaticUtils.isHexDigit(stringBytes[i+2]))
{
// Convert hex-encoded UTF-8 to 16-bit chars.
byte b;
byte escapedByte1 = stringBytes[++i];
switch (escapedByte1)
{
case '0':
b = (byte) 0x00;
break;
case '1':
b = (byte) 0x10;
break;
case '2':
b = (byte) 0x20;
break;
case '3':
b = (byte) 0x30;
break;
case '4':
b = (byte) 0x40;
break;
case '5':
b = (byte) 0x50;
break;
case '6':
b = (byte) 0x60;
break;
case '7':
b = (byte) 0x70;
break;
case '8':
b = (byte) 0x80;
break;
case '9':
b = (byte) 0x90;
break;
case 'a':
case 'A':
b = (byte) 0xA0;
break;
case 'b':
case 'B':
b = (byte) 0xB0;
break;
case 'c':
case 'C':
b = (byte) 0xC0;
break;
case 'd':
case 'D':
b = (byte) 0xD0;
break;
case 'e':
case 'E':
b = (byte) 0xE0;
break;
case 'f':
case 'F':
b = (byte) 0xF0;
break;
default:
throw new RuntimeException("Unexpected byte: "+escapedByte1);
}
byte escapedByte2 = stringBytes[++i];
switch (escapedByte2)
{
case '0':
break;
case '1':
b |= 0x01;
break;
case '2':
b |= 0x02;
break;
case '3':
b |= 0x03;
break;
case '4':
b |= 0x04;
break;
case '5':
b |= 0x05;
break;
case '6':
b |= 0x06;
break;
case '7':
b |= 0x07;
break;
case '8':
b |= 0x08;
break;
case '9':
b |= 0x09;
break;
case 'a':
case 'A':
b |= 0x0A;
break;
case 'b':
case 'B':
b |= 0x0B;
break;
case 'c':
case 'C':
b |= 0x0C;
break;
case 'd':
case 'D':
b |= 0x0D;
break;
case 'e':
case 'E':
b |= 0x0E;
break;
case 'f':
case 'F':
b |= 0x0F;
break;
default:
throw new RuntimeException("Unexpected byte: "+escapedByte2);
}
decodedBytes[pos++] = b;
}
else {
decodedBytes[pos++] = stringBytes[i];
}
}
return new String(decodedBytes, 0, pos, "UTF-8");
}
catch (UnsupportedEncodingException uee)
{
// This is a bug, UTF-8 should be supported always by the JVM
throw new RuntimeException("UTF-8 encoding not supported", uee);
}
}
/**
* Returns true if the the provided strings represent the same
* DN and false otherwise.
* @param dn1 the first dn to compare.
* @param dn2 the second dn to compare.
* @return true if the the provided strings represent the same
* DN and false otherwise.
*/
public static boolean areDnsEqual(String dn1, String dn2)
{
try
{
LdapName name1 = new LdapName(dn1);
LdapName name2 = new LdapName(dn2);
return name1.equals(name2);
} catch (Exception ex)
{
return false;
}
}
/**
* Gets the RDN string for a given attribute name and value.
* @param attrName the attribute name.
* @param attrValue the attribute value.
* @return the RDN string for the attribute name and value.
*/
public static String getRDNString(String attrName, String attrValue)
{
AttributeType attrType = DirectoryServer.getDefaultAttributeType(attrName);
RDN rdn = new RDN(attrType, attrName, ByteString.valueOf(attrValue));
return rdn.toString();
}
/**
* Returns the attribute name with no options (or subtypes).
* @param attrName the complete attribute name.
* @return the attribute name with no options (or subtypes).
*/
public static String getAttributeNameWithoutOptions(String attrName)
{
int index = attrName.indexOf(";");
if (index != -1)
{
attrName = attrName.substring(0, index);
}
return attrName;
}
/**
* Strings any potential "separator" from a given string.
* @param s string to strip
* @param separator the separator string to remove
* @return resulting string
*/
public static String stripStringToSingleLine(String s, String separator)
{
String o = null;
if (s != null)
{
o = s.replaceAll(separator, "");
}
return o;
}
/** The pattern for control characters. */
private static Pattern cntrl_pattern = Pattern.compile("\\p{Cntrl}", Pattern.MULTILINE);
/**
* Checks if a string contains control characters.
* @param s : the string to check
* @return true if s contains control characters, false otherwise
*/
public static Boolean hasControlCharaters(String s)
{
Matcher m = cntrl_pattern.matcher(s);
return m.find();
}
/**
* This is a helper method that gets a String representation of the elements
* in the Collection. The String will display the different elements separated
* by the separator String.
*
* @param col
* the collection containing the String.
* @param separator
* the separator String to be used.
* @return the String representation for the collection.
*/
public static String getStringFromCollection(Collectiontrue if the server located in the provided path
* is running and false otherwise.
* @param serverRootDirectory the path where the server is installed.
* @return true if the server located in the provided path
* is running and false otherwise.
*/
public static boolean isServerRunning(File serverRootDirectory)
{
String lockFileName = ServerConstants.SERVER_LOCK_FILE_NAME + ServerConstants.LOCK_FILE_SUFFIX;
String lockPathRelative = Installation.LOCKS_PATH_RELATIVE;
File locksPath = new File(serverRootDirectory, lockPathRelative);
String lockFile = new File(locksPath, lockFileName).getAbsolutePath();
StringBuilder failureReason = new StringBuilder();
try {
if (LockFileManager.acquireExclusiveLock(lockFile, failureReason))
{
LockFileManager.releaseLock(lockFile, failureReason);
return false;
}
return true;
}
catch (Throwable t) {
// Assume that if we cannot acquire the lock file the
// server is running.
return true;
}
}
private static final String VALID_SCHEMA_SYNTAX =
"abcdefghijklmnopqrstuvwxyz0123456789-";
/**
* Returns true if the provided string can be used as objectclass
* name and false otherwise.
* @param s the string to be analyzed.
* @return true if the provided string can be used as objectclass
* name and false otherwise.
*/
public static boolean isValidObjectclassName(String s)
{
if (s == null || s.length() == 0)
{
return false;
}
final StringCharacterIterator iter = new StringCharacterIterator(s, 0);
char c = iter.first();
while (c != CharacterIterator.DONE)
{
if (VALID_SCHEMA_SYNTAX.indexOf(Character.toLowerCase(c)) == -1)
{
return false;
}
c = iter.next();
}
return true;
}
/**
* Returns true if the provided string can be used as attribute
* name and false otherwise.
* @param s the string to be analyzed.
* @return true if the provided string can be used as attribute
* name and false otherwise.
*/
public static boolean isValidAttributeName(String s)
{
return isValidObjectclassName(s);
}
/**
* Returns the representation of the VLV index as it must be used in the
* command-line.
* @param index the VLV index.
* @return the representation of the VLV index as it must be used in the
* command-line.
*/
public static String getVLVNameInCommandLine(VLVIndexDescriptor index)
{
return "vlv."+index.getName();
}
/**
* Returns a string representing the VLV index in a cell.
* @param index the VLV index to be represented.
* @return the string representing the VLV index in a cell.
*/
public static String getVLVNameInCellRenderer(VLVIndexDescriptor index)
{
return INFO_CTRL_PANEL_VLV_INDEX_CELL.get(index.getName()).toString();
}
private static final String[] standardSchemaFileNames =
{
"00-core.ldif", "01-pwpolicy.ldif", "03-changelog.ldif",
"03-uddiv3.ldif", "05-solaris.ldif"
};
private static final String[] configurationSchemaOrigins =
{
"OpenDJ Directory Server", "OpenDS Directory Server",
"Sun Directory Server", "Microsoft Active Directory"
};
private static final String[] standardSchemaOrigins =
{
"Sun Java System Directory Server", "Solaris Specific", "X.501"
};
private static final String[] configurationSchemaFileNames =
{
"02-config.ldif", "06-compat.ldif"
};
/**
* Returns true if the provided schema element is part of the
* standard and false otherwise.
* @param fileElement the schema element.
* @return true if the provided schema element is part of the
* standard and false otherwise.
*/
public static boolean isStandard(SchemaFileElement fileElement)
{
final String fileName = getSchemaFile(fileElement);
if (fileName != null)
{
return contains(standardSchemaFileNames, fileName) || fileName.toLowerCase().indexOf("-rfc") != -1;
}
else if (fileElement instanceof CommonSchemaElements)
{
String xOrigin = getOrigin(fileElement);
if (xOrigin != null)
{
return contains(standardSchemaOrigins, xOrigin) || xOrigin.startsWith("RFC ") || xOrigin.startsWith("draft-");
}
}
return false;
}
/**
* Returns true if the provided schema element is part of the
* configuration and false otherwise.
* @param fileElement the schema element.
* @return true if the provided schema element is part of the
* configuration and false otherwise.
*/
public static boolean isConfiguration(SchemaFileElement fileElement)
{
String fileName = getSchemaFile(fileElement);
if (fileName != null)
{
return contains(configurationSchemaFileNames, fileName);
}
else if (fileElement instanceof CommonSchemaElements)
{
String xOrigin = getOrigin(fileElement);
if (xOrigin != null)
{
return contains(configurationSchemaOrigins, xOrigin);
}
}
return false;
}
private static boolean contains(String[] names, String toFind)
{
for (String name : names)
{
if (toFind.equals(name))
{
return true;
}
}
return false;
}
/**
* Returns the origin of the provided schema element.
* @param element the schema element.
* @return the origin of the provided schema element.
*/
public static String getOrigin(SchemaFileElement element)
{
return CommonSchemaElements.getSingleValueProperty(
element, ServerConstants.SCHEMA_PROPERTY_ORIGIN);
}
/**
* Returns the string representation of an attribute syntax.
* @param syntax the attribute syntax.
* @return the string representation of an attribute syntax.
*/
public static String getSyntaxText(AttributeSyntax> syntax)
{
String syntaxName = syntax.getName();
String syntaxOID = syntax.getOID();
if (syntaxName != null)
{
return syntaxName + " - " + syntaxOID;
}
return syntaxOID;
}
/**
* Returns true if the provided attribute has image syntax and
* false otherwise.
* @param attrName the name of the attribute.
* @param schema the schema.
* @return true if the provided attribute has image syntax and
* false otherwise.
*/
public static boolean hasImageSyntax(String attrName, Schema schema)
{
attrName = Utilities.getAttributeNameWithoutOptions(attrName).toLowerCase();
if ("photo".equals(attrName))
{
return true;
}
// Check all the attributes that we consider binaries.
if (schema != null)
{
AttributeType attr = schema.getAttributeType(attrName);
if (attr != null)
{
String syntaxOID = attr.getSyntax().getOID();
return SchemaConstants.SYNTAX_JPEG_OID.equals(syntaxOID);
}
}
return false;
}
/**
* Returns true if the provided attribute has binary syntax and
* false otherwise.
* @param attrName the name of the attribute.
* @param schema the schema.
* @return true if the provided attribute has binary syntax and
* false otherwise.
*/
public static boolean hasBinarySyntax(String attrName, Schema schema)
{
return attrName.toLowerCase().contains(";binary")
|| hasAnySyntax(attrName, schema, binarySyntaxOIDs);
}
/**
* Returns true if the provided attribute has password syntax and
* false otherwise.
* @param attrName the name of the attribute.
* @param schema the schema.
* @return true if the provided attribute has password syntax and
* false otherwise.
*/
public static boolean hasPasswordSyntax(String attrName, Schema schema)
{
return hasAnySyntax(attrName, schema, passwordSyntaxOIDs);
}
private static boolean hasAnySyntax(String attrName, Schema schema, String[] oids)
{
if (schema != null)
{
attrName = Utilities.getAttributeNameWithoutOptions(attrName).toLowerCase();
AttributeType attr = schema.getAttributeType(attrName);
if (attr != null)
{
return contains(oids, attr.getSyntax().getOID());
}
}
return false;
}
/**
* Returns the string representation of a matching rule.
* @param matchingRule the matching rule.
* @return the string representation of a matching rule.
*/
public static String getMatchingRuleText(MatchingRule matchingRule)
{
String nameOrOID = matchingRule.getNameOrOID();
String oid = matchingRule.getOID();
if (!nameOrOID.equals(oid))
{
// This is the name only
return nameOrOID + " - " + oid;
}
return oid;
}
/**
* Returns the InitialLdapContext to connect to the administration connector
* of the server using the information in the ControlCenterInfo object (which
* provides the host and administration connector port to be used) and some
* LDAP credentials.
* It also tests that the provided credentials have enough rights to read the
* configuration.
* @param controlInfo the object which provides the connection parameters.
* @param bindDN the base DN to be used to bind.
* @param pwd the password to be used to bind.
* @return the InitialLdapContext connected to the server.
* @throws NamingException if there was a problem connecting to the server
* or the provided credentials do not have enough rights.
* @throws ConfigReadException if there is an error reading the configuration.
*/
public static InitialLdapContext getAdminDirContext(
ControlPanelInfo controlInfo, String bindDN, String pwd)
throws NamingException, ConfigReadException
{
String usedUrl = controlInfo.getAdminConnectorURL();
if (usedUrl == null)
{
throw new ConfigReadException(
ERR_COULD_NOT_FIND_VALID_LDAPURL.get());
}
InitialLdapContext ctx = createLdapsContext(usedUrl,
bindDN, pwd, controlInfo.getConnectTimeout(), null,
controlInfo.getTrustManager(), null);
// Search for the config to check that it is the directory manager.
checkCanReadConfig(ctx);
return ctx;
}
/**
* Returns the InitialLdapContext to connect to the server using the
* information in the ControlCenterInfo object (which provides the host, port
* and protocol to be used) and some LDAP credentials. It also tests that
* the provided credentials have enough rights to read the configuration.
* @param controlInfo the object which provides the connection parameters.
* @param bindDN the base DN to be used to bind.
* @param pwd the password to be used to bind.
* @return the InitialLdapContext connected to the server.
* @throws NamingException if there was a problem connecting to the server
* or the provided credentials do not have enough rights.
* @throws ConfigReadException if there is an error reading the configuration.
*/
public static InitialLdapContext getUserDataDirContext(
ControlPanelInfo controlInfo,
String bindDN, String pwd) throws NamingException, ConfigReadException
{
InitialLdapContext ctx;
String usedUrl;
if (controlInfo.connectUsingStartTLS())
{
usedUrl = controlInfo.getStartTLSURL();
if (usedUrl == null)
{
throw new ConfigReadException(
ERR_COULD_NOT_FIND_VALID_LDAPURL.get());
}
ctx = Utils.createStartTLSContext(usedUrl,
bindDN, pwd, controlInfo.getConnectTimeout(), null,
controlInfo.getTrustManager(), null);
}
else if (controlInfo.connectUsingLDAPS())
{
usedUrl = controlInfo.getLDAPSURL();
if (usedUrl == null)
{
throw new ConfigReadException(
ERR_COULD_NOT_FIND_VALID_LDAPURL.get());
}
ctx = createLdapsContext(usedUrl,
bindDN, pwd, controlInfo.getConnectTimeout(), null,
controlInfo.getTrustManager(), null);
}
else
{
usedUrl = controlInfo.getLDAPURL();
if (usedUrl == null)
{
throw new ConfigReadException(
ERR_COULD_NOT_FIND_VALID_LDAPURL.get());
}
ctx = createLdapContext(usedUrl,
bindDN, pwd, controlInfo.getConnectTimeout(), null);
}
checkCanReadConfig(ctx);
return ctx;
}
/**
* Checks that the provided connection can read cn=config.
* @param ctx the connection to be tested.
* @throws NamingException if an error occurs while reading cn=config.
*/
public static void checkCanReadConfig(InitialLdapContext ctx)
throws NamingException
{
// Search for the config to check that it is the directory manager.
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
searchControls.setReturningAttributes(new String[] { SchemaConstants.NO_ATTRIBUTES });
NamingEnumeration