/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.task; import static org.opends.messages.AdminToolMessages.*; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.naming.NamingException; import javax.naming.directory.BasicAttribute; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.swing.SwingUtilities; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.ui.ColorAndFontConstants; import org.opends.guitools.controlpanel.ui.ProgressDialog; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.server.config.ConfigConstants; import org.opends.server.core.DirectoryServer; import org.opends.server.types.Attributes; import org.opends.server.types.AttributeType; import org.opends.server.types.CommonSchemaElements; import org.opends.server.types.Entry; import org.opends.server.types.ExistingFileBehavior; import org.opends.server.types.LDIFExportConfig; import org.opends.server.types.LDIFImportConfig; import org.opends.server.types.Modification; import org.opends.server.types.ModificationType; import org.opends.server.types.ObjectClass; import org.opends.server.types.OpenDsException; import org.opends.server.types.SchemaFileElement; import org.opends.server.util.LDIFReader; import org.opends.server.util.LDIFWriter; import org.opends.server.util.cli.CommandBuilder; /** * The task that is launched when a schema element must be deleted. */ public class DeleteSchemaElementsTask extends Task { ArrayList ocsToDelete = new ArrayList(); ArrayList attrsToDelete = new ArrayList(); private Set backendSet; /** * Constructor of the task. * @param info the control panel information. * @param dlg the progress dialog where the task progress will be displayed. * @param ocsToDelete the object classes that must be deleted. * @param attrsToDelete the attributes that must be deleted. */ public DeleteSchemaElementsTask(ControlPanelInfo info, ProgressDialog dlg, List ocsToDelete, List attrsToDelete) { super(info, dlg); this.ocsToDelete.addAll(ocsToDelete); this.attrsToDelete.addAll(attrsToDelete); backendSet = new HashSet(); } /** * {@inheritDoc} */ public Set getBackends() { return backendSet; } /** * {@inheritDoc} */ public boolean canLaunch(Task taskToBeLaunched, Collection incompatibilityReasons) { return true; } /** * {@inheritDoc} */ public Type getType() { if (attrsToDelete.isEmpty()) { return Type.DELETE_OBJECTCLASS; } else if (ocsToDelete.isEmpty()) { return Type.DELETE_ATTRIBUTE; } else { return Type.DELETE_OBJECTCLASS; } } /** * {@inheritDoc} */ public void runTask() { state = State.RUNNING; lastException = null; try { updateSchema(); state = State.FINISHED_SUCCESSFULLY; } catch (Throwable t) { lastException = t; state = State.FINISHED_WITH_ERROR; } } /** * {@inheritDoc} */ protected String getCommandLinePath() { return null; } /** * {@inheritDoc} */ protected ArrayList getCommandLineArguments() { return new ArrayList(); } /** * {@inheritDoc} */ public Message getTaskDescription() { return INFO_CTRL_PANEL_DELETE_SCHEMA_ELEMENT_TASK_DESCRIPTION.get(); } /** * Updates the schema. * @throws OpenDsException if an error occurs. */ private void updateSchema() throws OpenDsException { final boolean[] isFirst = {true}; final int totalNumber = ocsToDelete.size() + attrsToDelete.size(); int numberDeleted = 0; for (final ObjectClass objectClass : ocsToDelete) { SwingUtilities.invokeLater(new Runnable() { public void run() { if (!isFirst[0]) { getProgressDialog().appendProgressHtml("

"); } isFirst[0] = false; printEquivalentCommandToDelete(objectClass); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_DELETING_OBJECTCLASS.get( objectClass.getNameOrOID()), ColorAndFontConstants.progressFont)); } }); if (isServerRunning()) { try { BasicAttribute attr = new BasicAttribute( getSchemaFileAttributeName(objectClass)); attr.add(getSchemaFileAttributeValue(objectClass)); ModificationItem mod = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, attr); getInfo().getDirContext().modifyAttributes( ConfigConstants.DN_DEFAULT_SCHEMA_ROOT, new ModificationItem[] { mod }); } catch (NamingException ne) { throw new OnlineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(ne.toString()), ne); } } else { updateSchemaFile(objectClass); } numberDeleted ++; final int fNumberDeleted = numberDeleted; SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().getProgressBar().setIndeterminate(false); getProgressDialog().getProgressBar().setValue( (fNumberDeleted * 100) / totalNumber); getProgressDialog().appendProgressHtml( Utilities.getProgressDone(ColorAndFontConstants.progressFont)); } }); } for (final AttributeType attribute : attrsToDelete) { SwingUtilities.invokeLater(new Runnable() { public void run() { if (!isFirst[0]) { getProgressDialog().appendProgressHtml("

"); } isFirst[0] = false; printEquivalentCommandToDelete(attribute); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_DELETING_ATTRIBUTE.get( attribute.getNameOrOID()), ColorAndFontConstants.progressFont)); } }); if (isServerRunning()) { try { BasicAttribute attr = new BasicAttribute( getSchemaFileAttributeName(attribute)); attr.add(getSchemaFileAttributeValue(attribute)); ModificationItem mod = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, attr); getInfo().getDirContext().modifyAttributes( ConfigConstants.DN_DEFAULT_SCHEMA_ROOT, new ModificationItem[] { mod }); } catch (NamingException ne) { throw new OnlineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(ne.toString()), ne); } } else { updateSchemaFile(attribute); } numberDeleted ++; final int fNumberDeleted = numberDeleted; SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().getProgressBar().setIndeterminate(false); getProgressDialog().getProgressBar().setValue( (fNumberDeleted * 100) / totalNumber); getProgressDialog().appendProgressHtml( Utilities.getProgressDone(ColorAndFontConstants.progressFont)); } }); } } /** * Updates the schema file by deleting the provided schema element. * @param schemaElement the schema element to be deleted. * @throws OpenDsException if an error occurs. */ private void updateSchemaFile(CommonSchemaElements schemaElement) throws OpenDsException { String schemaFile = getSchemaFile((SchemaFileElement)schemaElement); LDIFExportConfig exportConfig = new LDIFExportConfig(schemaFile, ExistingFileBehavior.OVERWRITE); LDIFReader reader = null; Entry schemaEntry = null; try { reader = new LDIFReader(new LDIFImportConfig(schemaFile)); schemaEntry = reader.readEntry(); Modification mod = new Modification(ModificationType.DELETE, Attributes.create( getSchemaFileAttributeName(schemaElement).toLowerCase(), getSchemaFileAttributeValue(schemaElement))); schemaEntry.applyModification(mod); LDIFWriter writer = new LDIFWriter(exportConfig); writer.writeEntry(schemaEntry); exportConfig.getWriter().newLine(); } catch (Throwable t) { } finally { if (reader != null) { try { reader.close(); } catch (Throwable t) { } } if (exportConfig != null) { try { exportConfig.close(); } catch (Throwable t) { } } } } /** * Returns the schema file for a given schema element. * @param element the schema element. * @return the schema file for a given schema element. */ private String getSchemaFile(SchemaFileElement element) { String schemaFile = element.getSchemaFile(); if (schemaFile == null) { schemaFile = ConfigConstants.FILE_USER_SCHEMA_ELEMENTS; } File f = new File(schemaFile); if (!f.isAbsolute()) { f = new File( DirectoryServer.getEnvironmentConfig().getSchemaDirectory(false), schemaFile); if (f == null || ! f.exists() || f.isDirectory()) { f = new File( DirectoryServer.getEnvironmentConfig().getSchemaDirectory(true), schemaFile); } } schemaFile = f.getAbsolutePath(); return schemaFile; } /** * Returns the attribute name in the schema entry that corresponds to the * profived schema element. * @param element the schema element. * @return the attribute name in the schema entry that corresponds to the * profived schema element. */ private String getSchemaFileAttributeName(CommonSchemaElements element) { if (element instanceof AttributeType) { return "attributeTypes"; } else { return "objectClasses"; } } /** * Returns the value in the schema file for the provided element. * @param element the schema element. * @return the value in the schema file for the provided element. */ private String getSchemaFileAttributeValue(CommonSchemaElements element) { if (element instanceof AttributeType) { return ((AttributeType)element).getDefinition(); } else { return ((ObjectClass)element).getDefinition(); } } /** * Prints the equivalent command-line to delete the schema element in the * progress dialog. * @param element the schema element to be deleted. */ private void printEquivalentCommandToDelete(CommonSchemaElements element) { String schemaFile = getSchemaFile((SchemaFileElement)element); String attrName = getSchemaFileAttributeName(element); String attrValue = getSchemaFileAttributeValue(element); if (!isServerRunning()) { getProgressDialog().appendProgressHtml(Utilities.applyFont( INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_SCHEMA_ELEMENT_OFFLINE.get( schemaFile)+"
"+ attrName+": "+attrValue+"

", ColorAndFontConstants.progressFont)); } else { ArrayList args = new ArrayList(); args.add(getCommandLinePath("ldapmodify")); args.add("-a"); args.addAll(getObfuscatedCommandLineArguments( getConnectionCommandLineArguments(true, true))); args.add(getNoPropertiesFileArgument()); StringBuilder sb = new StringBuilder(); for (String arg : args) { sb.append(" "+CommandBuilder.escapeValue(arg)); } sb.append("
"); sb.append("dn: cn=schema
"); sb.append("changetype: modify
"); sb.append("delete: "+attrName+"
"); sb.append(attrName+": "+attrValue); getProgressDialog().appendProgressHtml(Utilities.applyFont( INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_SCHEMA_ELEMENT_ONLINE.get()+ "
"+sb.toString()+"

", ColorAndFontConstants.progressFont)); } } }