/*******************************************************************************
* Copyright (c) 2010 SAP AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Emil Simeonov - initial API and implementation.
* Dimitar Donchev - initial API and implementation.
* Dimitar Tenev - initial API and implementation.
* Nevena Manova - initial API and implementation.
* Georgi Konstantinov - initial API and implementation.
*******************************************************************************/
package org.eclipse.wst.sse.sieditor.command.emf.wsdl;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.wst.sse.core.internal.encoding.CommonEncodingPreferenceNames;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.ui.internal.adapters.commands.W11TopLevelElementCommand;
import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
import org.eclipse.wst.xsd.ui.internal.common.commands.BaseCommand;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.eclipse.wst.sse.sieditor.command.common.AbstractNotificationOperation;
import org.eclipse.wst.sse.sieditor.model.api.IModelRoot;
import org.eclipse.wst.sse.sieditor.model.utils.EmfXsdUtils;
import org.eclipse.wst.sse.sieditor.model.wsdl.api.IDescription;
/**
* Command creating default <?xml.. <definitions> wsdl element in a
* corrupted or empty document. <br>
* <br>
* note: if included in a composite command execution in separate transaction
* should be preffered, due to custom implementation of undo/redo
*
*/
public class EnsureDefinitionCommand extends AbstractNotificationOperation {
private final boolean hasXmlTag;
private final boolean hasDefinitionsElement;
public EnsureDefinitionCommand(final IModelRoot root, final IDescription modelObject, final String operationLabel) {
super(root, modelObject, operationLabel);
final Definition definitions = modelObject.getComponent();
hasDefinitionsElement = definitions.getElement() != null;
hasXmlTag = EmfXsdUtils.hasXmlTag(definitions.getDocument());
}
@Override
public boolean canExecute() {
final IDescription iDescription = (IDescription) getModelObjects()[0];
if (iDescription == null) {
return false;
}
final Definition component = iDescription.getComponent();
return (component != null) && (component.getDocument() != null) && !hasDefinitionsElement && super.canExecute();
}
@Override
public IStatus run(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
final Definition definition = ((IDescription) getModelObjects()[0]).getComponent();
if (!hasXmlTag) {
ensureXmlDirective(definition);
}
W11TopLevelElementCommand.ensureDefinition(definition);
if (!hasDefinitionsElement)
definition.eNotify(new ENotificationImpl((InternalEObject) definition, Notification.ADD, null, null, definition));
return Status.OK_STATUS;
}
// =========================================================
// eclipse bug 321851 workarounds:
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=321851
// =========================================================
private void ensureXmlDirective(final Definition definition) {
Node firstChild = definition.getDocument().getFirstChild();
ProcessingInstruction xmlDeclaration = getXMLDeclaration(definition.getDocument());
definition.getDocument().insertBefore(xmlDeclaration, firstChild);
// explicitly fire an ADD event for the added xml directive
definition.eNotify(new ENotificationImpl((InternalEObject) definition, Notification.ADD, null, null, xmlDeclaration));
}
/**
* this method is copy of {@link BaseCommand#getXMLDeclaration}
*
* @param document
* @return
*/
private static ProcessingInstruction getXMLDeclaration(Document document) {
Preferences preference = XMLCorePlugin.getDefault().getPluginPreferences();
String charSet = preference.getString(CommonEncodingPreferenceNames.OUTPUT_CODESET);
if (charSet == null || charSet.trim().equals("")) { //$NON-NLS-1$
charSet = "UTF-8"; //$NON-NLS-1$
}
ProcessingInstruction xmlDeclaration = document.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"" //$NON-NLS-1$ //$NON-NLS-2$
+ charSet + "\""); //$NON-NLS-1$
return xmlDeclaration;
}
}