diff options
author | Mark Brörkens | 2013-10-10 16:38:28 +0000 |
---|---|---|
committer | Mark Brörkens | 2013-10-10 16:38:28 +0000 |
commit | fd81670f0089e768d9ef65ec98c41eb1347ef827 (patch) | |
tree | bf111694224e8f52e50b893916b386760b9cf68c | |
parent | dde808008231fa2dee8a3fda2c8dda515a3d6b32 (diff) | |
download | org.eclipse.rmf-fd81670f0089e768d9ef65ec98c41eb1347ef827.tar.gz org.eclipse.rmf-fd81670f0089e768d9ef65ec98c41eb1347ef827.tar.xz org.eclipse.rmf-fd81670f0089e768d9ef65ec98c41eb1347ef827.zip |
ASSIGNED - bug 407538: Support XHTML Content as String
https://bugs.eclipse.org/bugs/show_bug.cgi?id=407538
added adapter for reading and writing xhtml as string
3 files changed, 262 insertions, 1 deletions
diff --git a/org.eclipse.rmf.reqif10.common/META-INF/MANIFEST.MF b/org.eclipse.rmf.reqif10.common/META-INF/MANIFEST.MF index 3e4c1b15..c66510d0 100644 --- a/org.eclipse.rmf.reqif10.common/META-INF/MANIFEST.MF +++ b/org.eclipse.rmf.reqif10.common/META-INF/MANIFEST.MF @@ -6,7 +6,9 @@ Bundle-SymbolicName: org.eclipse.rmf.reqif10.common Bundle-Version: 0.8.0.qualifier Bundle-Activator: org.eclipse.rmf.reqif10.internal.common.Activator Require-Bundle: org.eclipse.core.runtime, - org.eclipse.rmf.reqif10;bundle-version="0.8.0" + org.eclipse.rmf.reqif10;bundle-version="0.8.0", + org.apache.xerces, + org.eclipse.rmf.reqif10.xhtml Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName Export-Package: org.eclipse.rmf.reqif10.common.util diff --git a/org.eclipse.rmf.reqif10.common/src/org/eclipse/rmf/reqif10/common/util/ReqIF10XHTMLContentAdapter.java b/org.eclipse.rmf.reqif10.common/src/org/eclipse/rmf/reqif10/common/util/ReqIF10XHTMLContentAdapter.java new file mode 100644 index 00000000..aa01e1d4 --- /dev/null +++ b/org.eclipse.rmf.reqif10.common/src/org/eclipse/rmf/reqif10/common/util/ReqIF10XHTMLContentAdapter.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2013 itemis 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: + * itemis AG - initial API and implementation + ******************************************************************************/ +package org.eclipse.rmf.reqif10.common.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.xerces.impl.Constants; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.EMap; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.Resource.Diagnostic; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.emf.ecore.xmi.XMLHelper; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.eclipse.emf.ecore.xmi.XMLSave; +import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl; +import org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl; +import org.eclipse.rmf.reqif10.XhtmlContent; +import org.eclipse.rmf.reqif10.xhtml.XhtmlPackage; + +public class ReqIF10XHTMLContentAdapter extends EContentAdapter { + String xmlString = null; + XMLResource resource = null; + static final String UTF8 = "UTF-8"; //$NON-NLS-1$ + XhtmlContent xhtmlContent = null; + + public String getXhtmlString() { + if (null == xmlString) { + updateXhtmlString(); + } + + return xmlString; + } + + public void setXhtmlString(String xhtmlString) throws IOException { + // set object tree in model + updateXhtmlObjects(xhtmlString); + // the xhtml String is updated automatically from updated xhtml objects + // TODO: analyze if it would be sufficient not to recreate the xhtml string from the xhtml object structure + } + + public EList<Diagnostic> getErrors() { + return resource.getErrors(); + } + + public EList<Diagnostic> getWarnings() { + return resource.getWarnings(); + } + + @Override + public boolean isAdapterForType(Object type) { + return ReqIF10XHTMLContentAdapter.class == type; + } + + @Override + public void notifyChanged(Notification notification) { + super.notifyChanged(notification); + Object notifier = notification.getNotifier(); + if (notifier instanceof XhtmlContent) { + updateXhtmlString(); + } + } + + private void updateXhtmlString() { + assert null != xhtmlContent; + EObject xmlRoot = xhtmlContent.getXhtml(); + + if (null != xmlRoot) { + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + XMLResource resource = getResource(); + Map<Object, Object> options = new HashMap<Object, Object>(); + options.put(XMLResource.OPTION_ROOT_OBJECTS, Collections.singletonList(xmlRoot)); + resource.save(byteArrayOutputStream, options); + + xmlString = new String(byteArrayOutputStream.toByteArray(), UTF8); + } catch (IOException ioe) { + assert false : "We should always be able to update the xhtml string from the given object model"; //$NON-NLS-1$ + } + } + } + + private void updateXhtmlObjects(String xmlString) throws IOException { + assert null != xhtmlContent; + if (null == xmlString) { + // unset the xhtmlContent + xhtmlContent.unsetXhtml(); + } else { + // parse the string + + Resource resource = getResource(); + resource.load(new ByteArrayInputStream(xmlString.getBytes(UTF8)), null); + EList<EObject> contents = resource.getContents(); + if (0 < contents.size()) { + EObject rootObject = contents.get(0); + xhtmlContent.setXhtml(rootObject); + } + } + + } + + private XMLResource getResource() { + if (null == resource) { + resource = new NestedXMLResourceImpl(); + + } else { + resource.getContents().clear(); + } + return resource; + } + + @Override + public void setTarget(Notifier target) { + super.setTarget(target); + if (target instanceof XhtmlContent) { + xhtmlContent = (XhtmlContent) target; + } + } + + private class NestedXMLResourceImpl extends XMLResourceImpl { + @Override + protected XMLHelper createXMLHelper() { + XMLHelper helper = super.createXMLHelper(); + // make sure that no namespace prefix is created during serialization + EMap<String, String> prefixToNamespaceMap = helper.getPrefixToNamespaceMap(); + prefixToNamespaceMap.put("", XhtmlPackage.eNS_URI); //$NON-NLS-1$ + helper.setPrefixToNamespaceMap(prefixToNamespaceMap); + + // make sure that missing namespace declaration is mapped to Xhtml + helper.pushContext(); + helper.addPrefix("", XhtmlPackage.eNS_URI);//$NON-NLS-1$ + return helper; + } + + @Override + protected XMLSave createXMLSave() { + return new XMLSaveImpl(createXMLHelper()) { + @Override + protected Object writeTopObject(EObject top) { + EClass eClass = top.eClass(); + String name = helper.getQName(eClass); + doc.startElement(name); + Object mark = doc.mark(); + root = top; + saveElementID(top); + return mark; + } + }; + } + + @Override + protected void init() { + // make sure that the xhtml package is registered + Object dummy = XhtmlPackage.eINSTANCE; + setEncoding(UTF8); + Map<Object, Object> loadOptions = getDefaultLoadOptions(); + loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); + loadOptions.put(XMLResource.OPTION_USE_DEPRECATED_METHODS, Boolean.FALSE); + // avoid creation of document root element + loadOptions.put(XMLResource.OPTION_SUPPRESS_DOCUMENT_ROOT, Boolean.TRUE); + // performance improvement: delays the attachment of adapters until all elements are loaded. + loadOptions.put(XMLResource.OPTION_DEFER_ATTACHMENT, Boolean.TRUE); + + Map<String, Object> parserProperties = new HashMap<String, Object>(); + parserProperties.put(Constants.XERCES_PROPERTY_PREFIX + Constants.BUFFER_SIZE_PROPERTY, 1024); + + Map<String, Boolean> parserFeatures = new HashMap<String, Boolean>(); + parserFeatures.put(Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE, true); + parserFeatures.put(Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE, false); + loadOptions.put(XMLResource.OPTION_PARSER_FEATURES, parserFeatures); + loadOptions.put(XMLResource.OPTION_PARSER_PROPERTIES, parserProperties); + + Map<Object, Object> saveOptions = getDefaultSaveOptions(); + saveOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); + saveOptions.put(XMLResource.OPTION_DECLARE_XML, Boolean.FALSE); + saveOptions.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, Boolean.FALSE); + saveOptions.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE); + saveOptions.put(XMLResource.OPTION_USE_DEPRECATED_METHODS, Boolean.FALSE); + super.init(); + } + } + +} diff --git a/org.eclipse.rmf.reqif10.common/src/org/eclipse/rmf/reqif10/common/util/ReqIF10XHTMLContentAdapterFactory.java b/org.eclipse.rmf.reqif10.common/src/org/eclipse/rmf/reqif10/common/util/ReqIF10XHTMLContentAdapterFactory.java new file mode 100644 index 00000000..a751ad07 --- /dev/null +++ b/org.eclipse.rmf.reqif10.common/src/org/eclipse/rmf/reqif10/common/util/ReqIF10XHTMLContentAdapterFactory.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2013 itemis 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: + * itemis AG - initial API and implementation + ******************************************************************************/ +package org.eclipse.rmf.reqif10.common.util; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.rmf.reqif10.util.ReqIF10AdapterFactory; + +public class ReqIF10XHTMLContentAdapterFactory extends ReqIF10AdapterFactory { + + /** + * This keeps track of all the supported types checked by {@link #isFactoryForType isFactoryForType}. <!-- + * begin-user-doc --> <!-- end-user-doc --> + * + * @generated + */ + protected Collection<Object> supportedTypes = new ArrayList<Object>(); + + /** + * This constructs an instance. <!-- begin-user-doc --> <!-- end-user-doc --> + * + * @generated + */ + public ReqIF10XHTMLContentAdapterFactory() { + supportedTypes.add(ReqIF10XHTMLContentAdapter.class); + } + + /** + * This keeps track of the one adapter used for all {@link org.eclipse.rmf.reqif10.XhtmlContent} instances. <!-- + * begin-user-doc --> <!-- end-user-doc --> + */ + protected ReqIF10XHTMLContentAdapter xhtmlContentAdapter; + + /** + * This creates an adapter for a {@link org.eclipse.rmf.reqif10.XhtmlContent}. <!-- begin-user-doc --> <!-- + * end-user-doc --> + */ + @Override + public Adapter createXhtmlContentAdapter() { + return new ReqIF10XHTMLContentAdapter(); + } + + @Override + public boolean isFactoryForType(Object type) { + return supportedTypes.contains(type) || super.isFactoryForType(type); + } + +} |