package org.ebayopensource.turmeric.eclipse.typelibrary.ui;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;
import org.ebayopensource.turmeric.common.config.LibraryType;
import org.ebayopensource.turmeric.common.config.TypeLibraryType;
import org.ebayopensource.turmeric.eclipse.buildsystem.SynchronizeWsdlAndDepXML;
import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger;
import org.ebayopensource.turmeric.eclipse.core.model.TemplateModel;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOATypeLibraryConstants;
import org.ebayopensource.turmeric.eclipse.exception.core.CommandFailedException;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.SOAGlobalRegistryAdapter;
import org.ebayopensource.turmeric.eclipse.typelibrary.ui.resources.TypeLibMoveDeleteHook;
import org.ebayopensource.turmeric.eclipse.typelibrary.ui.wst.AddImportCommand;
import org.ebayopensource.turmeric.eclipse.typelibrary.utils.TypeLibraryUtil;
import org.ebayopensource.turmeric.eclipse.ui.model.typelib.ComplexTypeParamModel;
import org.ebayopensource.turmeric.eclipse.ui.model.typelib.ComplexTypeSCParamModel;
import org.ebayopensource.turmeric.eclipse.utils.plugin.JDTUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.ProgressUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.WorkspaceUtil;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.wst.sse.core.internal.format.IStructuredFormatProcessor;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
import org.eclipse.wst.xsd.ui.internal.common.util.XSDCommonUIUtils;
import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDComplexTypeContent;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDModelGroupDefinition;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.osgi.framework.BundleContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* The activator class controls the plug-in life cycle.
*/
public class TypeLibraryUIActivator extends AbstractUIPlugin {
// The plug-in ID
/** The Constant PLUGIN_ID. */
public static final String PLUGIN_ID = "org.ebayopensource.turmeric.eclipse.typelibrary.ui"; //$NON-NLS-1$
/** The Constant ICON_PATH. */
public static final String ICON_PATH = "icons/";
// The shared instance
private static TypeLibraryUIActivator plugin;
private TypeLibMoveDeleteHook typeLibMoveDeleteHook;
/**
* The constructor.
*/
public TypeLibraryUIActivator() {
}
/**
* {@inheritDoc}
*/
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
StringBuffer buf = new StringBuffer();
buf.append("SOAPlugin.start - ");
buf.append(JDTUtil.getBundleInfo(context.getBundle(), SOALogger.DEBUG));
SOALogger.getLogger().info(buf);
typeLibMoveDeleteHook = new TypeLibMoveDeleteHook();
ResourcesPlugin.getWorkspace().addResourceChangeListener(
typeLibMoveDeleteHook, IResourceChangeEvent.POST_CHANGE);
}
/**
* {@inheritDoc}
*/
@Override
public void stop(BundleContext context) throws Exception {
if (typeLibMoveDeleteHook != null)
ResourcesPlugin.getWorkspace().removeResourceChangeListener(
typeLibMoveDeleteHook);
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance.
*
* @return the shared instance
*/
public static TypeLibraryUIActivator getDefault() {
return plugin;
}
/**
* Adds the element declaration.
*
* @param complexTypeDefinition
* the complex type definition
* @param model
* the model
* @param elementName
* the element name
* @param elementType
* the element type
* @param minOccurs
* the min occurs
* @param maxOccurs
* the max occurs
* @throws CommandFailedException
* the command failed exception
*/
public static void addElementDeclaration(
XSDComplexTypeDefinition complexTypeDefinition,
ComplexTypeParamModel model, String elementName,
Object elementType, int minOccurs, int maxOccurs)
throws CommandFailedException {
String prefixedElementType = "";
boolean isPrimitive = true;
try {
if (elementType instanceof String) {
prefixedElementType = getPrefix(
complexTypeDefinition.getSchema(),
SOATypeLibraryConstants.W3C_NAMEPSACE) + elementType;
} else {
isPrimitive = false;
LibraryType libElementType = (LibraryType) elementType;
prefixedElementType = getPrefix(
complexTypeDefinition.getSchema(),
TypeLibraryUtil.getNameSpace(libElementType))
+ libElementType.getName();
}
} catch (Exception e) {
throw new CommandFailedException(
"Could not get the name space for the type "
+ elementType
+ " from the registry. Please fix this issue and try again.");
}
XSDParticle xsdParticle = createXSDElementDeclaration(elementName,
prefixedElementType, minOccurs, maxOccurs);
XSDModelGroup xsdModelGroup = getModelGroup(complexTypeDefinition);
xsdModelGroup.getContents().add(0, xsdParticle);
if (!isPrimitive)
addImport((LibraryType) elementType, complexTypeDefinition,
model.getTypeName(), model.getVersion(),
model.getTypeLibraryName());
}
/** The Constant NO_OCCURS. */
public static final int NO_OCCURS = -2;
/** The Constant UNBOUND. */
public static final int UNBOUND = -1;
/**
* Adds the attribute declarations.
*
* @param complexTypeDefinition
* the complex type definition
* @param model
* the model
* @param attrName
* the attr name
* @param attrType
* the attr type
* @param attrDoc
* the attr doc
* @throws CommandFailedException
* the command failed exception
*/
public static void addAttributeDeclarations(
XSDComplexTypeDefinition complexTypeDefinition,
ComplexTypeSCParamModel model, String attrName, Object attrType,
String attrDoc) throws CommandFailedException {
String prefixedAttrType = "";
boolean isPrimitive = true;
try {
if (attrType instanceof String) {// this is a primitive type
prefixedAttrType = getPrefix(complexTypeDefinition.getSchema(),
SOATypeLibraryConstants.W3C_NAMEPSACE) + attrType;
} else {// this is a library Type
isPrimitive = false;
LibraryType libAttrType = (LibraryType) attrType;
prefixedAttrType = getPrefix(complexTypeDefinition.getSchema(),
TypeLibraryUtil.getNameSpace(libAttrType))
+ libAttrType.getName();
}
} catch (Exception e) {
throw new CommandFailedException(
"Could not get the name space for the type "
+ attrType
+ " from the registry. Please fix this issue and try again.");
}
XSDAttributeUse attr = createXSDAttrDeclaration(attrName,
prefixedAttrType);
complexTypeDefinition.getAttributeContents().add(attr);
if (!isPrimitive)
addImport((LibraryType) attrType, complexTypeDefinition,
model.getTypeName(), model.getVersion(),
model.getTypeLibraryName());
addDocumentation(attr.getAttributeDeclaration(), attrDoc);
}
/**
* Format contents.
*
* @param contents
* the contents
* @return the string
* @throws IOException
* Signals that an I/O exception has occurred.
* @throws CoreException
* the core exception
*/
public static String formatContents(String contents) throws IOException,
CoreException {
FormatProcessorXML formatProcessor = new FormatProcessorXML();
return formatProcessor.formatContent(contents);
}
private static void addImport(LibraryType importType,
XSDTypeDefinition typeDefinition, String typeName, String version,
String typeLibraryName) throws CommandFailedException {
try {
XSDSchema importSchema = TypeLibraryUtil
.parseSchema(TypeLibraryUtil
.getXSD(SOAGlobalRegistryAdapter
.getInstance()
.getGlobalRegistry()
.getType(
TypeLibraryUtil.toQName(importType))));
AddImportCommand addImportCommand = new AddImportCommand(
typeDefinition.getSchema(),
TypeLibraryUtil.getProtocolString(importType), importSchema);
addImportCommand.run();
// for add type to wsdl, Type Library is null
if (typeLibraryName == null) {
return;
}
TypeLibraryType typeLibInfo = SOAGlobalRegistryAdapter
.getInstance().getGlobalRegistry()
.getTypeLibrary(typeLibraryName);
LibraryType libraryType = TypeLibraryUtil.getLibraryType(typeName,
version, typeLibInfo);
SOAGlobalRegistryAdapter.getInstance().addTypeToRegistry(
libraryType);
IProject project = WorkspaceUtil.getProject(typeLibraryName);
SynchronizeWsdlAndDepXML synch = new SynchronizeWsdlAndDepXML(
project);
synch.syncronizeXSDandDepXml(typeDefinition.getSchema(),
TypeLibraryUtil.toQName(libraryType));
synch.synchronizeTypeDepandProjectDep(ProgressUtil
.getDefaultMonitor(null));
} catch (Exception e) {
throw new CommandFailedException(e);
}
}
/**
* Gets the image from registry.
*
* @param path
* the path
* @return the image from registry
*/
public static ImageDescriptor getImageFromRegistry(String path) {
if (path == null)
return null;
path = StringUtils.replaceChars(path, '\\', '/');
final String iconPath = path.startsWith(ICON_PATH) ? path : ICON_PATH
+ path;
ImageDescriptor image = getDefault().getImageRegistry().getDescriptor(
iconPath);
if (image == null) {
final ImageDescriptor descriptor = imageDescriptorFromPlugin(
PLUGIN_ID, iconPath);
if (descriptor != null) {
getDefault().getImageRegistry().put(iconPath, descriptor);
image = getDefault().getImageRegistry().getDescriptor(iconPath);
}
}
return image;
}
/**
* Gets the image descriptor.
*
* @param path
* the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(final String path) {
ImageDescriptor descriptor = imageDescriptorFromPlugin(PLUGIN_ID, path);
return descriptor;
}
/**
* Format child.
*
* @param child
* the child
*/
public static void formatChild(Element child) {
if (child instanceof IDOMNode) {
IDOMModel model = ((IDOMNode) child).getModel();
try {
model.aboutToChangeModel();
IStructuredFormatProcessor formatProcessor = new FormatProcessorXML();
formatProcessor.formatNode(child);
} finally {
model.changedModel();
}
}
}
/**
* Adds the documentation.
*
* @param component
* the component
* @param docText
* the doc text
*/
public static void addDocumentation(XSDConcreteComponent component,
String docText) {
XSDAnnotation xsdAnnotation = XSDCommonUIUtils.getInputXSDAnnotation(
component, true);
Element element = xsdAnnotation.getElement();
List documentationList = xsdAnnotation.getUserInformation();
Element documentationElement = null;
boolean documentationExists = false;
if (documentationList.size() > 0) {
documentationExists = true;
documentationElement = (Element) documentationList.get(0);
}
if (documentationElement == null) {
documentationElement = xsdAnnotation.createUserInformation(null);
element.appendChild(documentationElement);
formatChild(documentationElement);
xsdAnnotation.updateElement();
xsdAnnotation.setElement(element);
}
if (documentationElement.hasChildNodes()) {
if (documentationElement instanceof IDOMElement) {
IDOMElement domElement = (IDOMElement) documentationElement;
Node firstChild = documentationElement.getFirstChild();
Node lastChild = documentationElement.getLastChild();
int start = 0;
int end = 0;
IDOMNode first = null;
if (firstChild instanceof IDOMNode) {
first = (IDOMNode) firstChild;
start = first.getStartOffset();
}
if (lastChild instanceof IDOMNode) {
IDOMNode last = (IDOMNode) lastChild;
end = last.getEndOffset();
}
if (domElement != null) {
domElement
.getModel()
.getStructuredDocument()
.replaceText(documentationElement, start,
end - start, docText);
}
}
} else {
if (docText.length() > 0) {
Node childNode = documentationElement.getOwnerDocument()
.createTextNode(docText);
documentationElement.appendChild(childNode);
}
}
formatChild(xsdAnnotation.getElement());
}
/**
* Gets the model group.
*
* @param cType
* the c type
* @return the model group
*/
public static XSDModelGroup getModelGroup(XSDComplexTypeDefinition cType) {
XSDParticle particle = null;
XSDComplexTypeContent xsdComplexTypeContent = cType.getContent();
if (xsdComplexTypeContent instanceof XSDParticle) {
particle = (XSDParticle) xsdComplexTypeContent;
}
if (particle == null) {
return null;
}
Object particleContent = particle.getContent();
XSDModelGroup group = null;
if (particleContent instanceof XSDModelGroupDefinition) {
group = ((XSDModelGroupDefinition) particleContent)
.getResolvedModelGroupDefinition().getModelGroup();
} else if (particleContent instanceof XSDModelGroup) {
group = (XSDModelGroup) particleContent;
}
if (group == null) {
return null;
}
return group;
}
/**
* Gets the prefix.
*
* @param schema
* the schema
* @param nameSpace
* the name space
* @return the prefix
*/
public static String getPrefix(XSDSchema schema, String nameSpace) {
Map<String, String> qNamesMap = schema.getQNamePrefixToNamespaceMap();
if (qNamesMap.containsValue(nameSpace)) {
for (Entry<String, String> entry : qNamesMap.entrySet()) {
if (StringUtils.equals(entry.getValue(), nameSpace)) {
return entry.getKey() + SOATypeLibraryConstants.COLON;
}
}
}
int prefixInt = 0;
while (true) {
prefixInt++;
if (!qNamesMap
.containsKey(SOATypeLibraryConstants.DEFAULT_TNS_PREFIX
+ prefixInt))
break;
}
String prefix = SOATypeLibraryConstants.DEFAULT_TNS_PREFIX + prefixInt;
qNamesMap.put(prefix, nameSpace);
return prefix + SOATypeLibraryConstants.COLON;
}
/**
* Creates the xsd element declaration.
*
* @param strName
* the str name
* @param strType
* the str type
* @param minOccurs
* the min occurs
* @param maxOccurs
* the max occurs
* @return the xSD particle
*/
public static XSDParticle createXSDElementDeclaration(String strName,
String strType, int minOccurs, int maxOccurs) {
XSDSimpleTypeDefinition type = XSDFactory.eINSTANCE
.createXSDSimpleTypeDefinition();
type.setName(strType);
XSDElementDeclaration element = XSDFactory.eINSTANCE
.createXSDElementDeclaration();
element.setName(StringUtils.defaultString(strName)); //$NON-NLS-1$
element.setTypeDefinition(type);
XSDParticle particle = XSDFactory.eINSTANCE.createXSDParticle();
particle.setContent(element);
// -2 means no Occurs attribute
if (minOccurs != NO_OCCURS) {
particle.setMinOccurs(minOccurs);
}
if (maxOccurs != NO_OCCURS) {
particle.setMaxOccurs(maxOccurs);
}
return particle;
}
private static XSDAttributeUse createXSDAttrDeclaration(String strName,
String strType) {
XSDSimpleTypeDefinition type = XSDFactory.eINSTANCE
.createXSDSimpleTypeDefinition();
type.setName(strType);
XSDAttributeDeclaration attribute = XSDFactory.eINSTANCE
.createXSDAttributeDeclaration();
attribute.setName(StringUtils.defaultString(strName)); //$NON-NLS-1$
attribute.setTypeDefinition(type);
XSDAttributeUse attributeUse = XSDFactory.eINSTANCE
.createXSDAttributeUse();
attributeUse.setAttributeDeclaration(attribute);
attributeUse.setContent(attribute);
return attributeUse;
}
/**
* Sets the base type for complex types.
*
* @param complexTypeDefinition
* the complex type definition
* @param baseType
* the base type
* @param typeName
* the type name
* @param typeLibraryName
* the type library name
* @param version
* the version
* @throws CommandFailedException
* the command failed exception
*/
public static void setBaseTypeForComplexTypes(
XSDComplexTypeDefinition complexTypeDefinition, Object baseType,
String typeName, String typeLibraryName, String version)
throws CommandFailedException {
XSDComplexTypeDefinition restriction = XSDFactory.eINSTANCE
.createXSDComplexTypeDefinition();
boolean isPrimitive = true;
try {
if (baseType instanceof String)
restriction.setName(getPrefix(
complexTypeDefinition.getSchema(),
SOATypeLibraryConstants.W3C_NAMEPSACE)
+ baseType);
else {
isPrimitive = false;
LibraryType libBaseType = (LibraryType) baseType;
restriction.setName(getPrefix(
complexTypeDefinition.getSchema(),
TypeLibraryUtil.getNameSpace(libBaseType))
+ libBaseType.getName());
}
} catch (Exception e) {
throw new CommandFailedException(
"Could not get the name space for the type "
+ baseType
+ " from the registry. Please fix this issue and try again.");
}
complexTypeDefinition.setBaseTypeDefinition(restriction);
if (!isPrimitive) {
addImport((LibraryType) baseType, complexTypeDefinition, typeName,
version, typeLibraryName);
}
}
public static TemplateModel processTemplateModel(InputStream inputStream)
throws CoreException, IOException {
TemplateModel templateModel = new TemplateModel();
XSDSchema schema = TypeLibraryUtil.parseSchema(inputStream);
if (schema.getTypeDefinitions() != null
&& schema.getTypeDefinitions().size() > 0
&& schema.getTypeDefinitions().get(0) != null
&& schema.getTypeDefinitions().get(0) instanceof XSDTypeDefinition) {
XSDAnnotation xsdAnnotation = XSDCommonUIUtils
.getInputXSDAnnotation((XSDTypeDefinition) schema
.getTypeDefinitions().get(0), false);
if (xsdAnnotation != null) {
List documentationList = xsdAnnotation.getUserInformation();
if (documentationList.size() > 0) {
Element documentationElement = (Element) documentationList
.get(0);
templateModel.setDocumentation(documentationElement
.getTextContent());
}
}
}
return templateModel;
}
}