From f96e4e4a3969bfaaee61fa5da5ebd8241d4c1c02 Mon Sep 17 00:00:00 2001 From: jomu Date: Mon, 2 Feb 2015 18:41:01 +0000 Subject: [PATCH] implemented first basic lists handling functions --- sharepoint/api/pom.xml | 181 +++++++++++++----- .../shared/sharepoint/api/SPContext.java | 46 ++++- .../shared/sharepoint/api/SPJaxbObject.java | 161 ++++++++++++++++ .../shared/sharepoint/api/SPObject.java | 45 ++++- .../api/SPValidationEventHandler.java | 50 +++++ .../sharepoint/api/ServiceLogHandler.java | 66 +++++++ .../api/authentication/SPAuthentication.java | 7 - .../shared/sharepoint/api/lists/SPBatch.java | 39 ++++ .../shared/sharepoint/api/lists/SPList.java | 154 ++++++++++++++- .../shared/sharepoint/api/lists/SPMethod.java | 48 +++++ .../shared/sharepoint/api/sites/SPSite.java | 16 +- .../api/src/main/resources/jaxb/batch.xml | 12 ++ .../api/src/main/resources/jaxb/lists.xml | 12 ++ .../api/src/main/resources/xsd/batch.xsd | 37 ++++ .../api/src/main/resources/xsd/lists.xsd | 79 ++++++++ .../sharepoint/api/lists/SPListTest.java | 75 ++++++++ .../src/test/resources/BatchImportTest.xml | 17 ++ .../api/src/test/resources/BatchTest.xml | 17 ++ sharepoint/pom.xml | 2 +- 19 files changed, 998 insertions(+), 66 deletions(-) create mode 100644 sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPJaxbObject.java create mode 100644 sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPValidationEventHandler.java create mode 100644 sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/ServiceLogHandler.java create mode 100644 sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPBatch.java create mode 100644 sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPMethod.java create mode 100644 sharepoint/api/src/main/resources/jaxb/batch.xml create mode 100644 sharepoint/api/src/main/resources/jaxb/lists.xml create mode 100644 sharepoint/api/src/main/resources/xsd/batch.xsd create mode 100644 sharepoint/api/src/main/resources/xsd/lists.xsd create mode 100644 sharepoint/api/src/test/java/de/muehlencord/shared/sharepoint/api/lists/SPListTest.java create mode 100644 sharepoint/api/src/test/resources/BatchImportTest.xml create mode 100644 sharepoint/api/src/test/resources/BatchTest.xml diff --git a/sharepoint/api/pom.xml b/sharepoint/api/pom.xml index 3f01a78..6ec6af0 100644 --- a/sharepoint/api/pom.xml +++ b/sharepoint/api/pom.xml @@ -1,29 +1,70 @@ - + 4.0.0 - + de.muehlencord.shared - sharepoint + shared-sharepoint 1.0-SNAPSHOT - + api jar api - + - + + + + + + org.codehaus.mojo + properties-maven-plugin + 1.0-alpha-2 + + + set-additional-system-properties + + set-system-properties + + + + + + + javax.xml.accessExternalSchema + file,http + + + + + + + + org.jvnet.jax-ws-commons jaxws-maven-plugin - 2.2 - + 2.2 + - ${project.build.directory}/generated-sources/jaxws-wsimport + ${project.build.directory}/generated-sources/jaxws-wsimport - + authentication2010 @@ -32,17 +73,13 @@ wsimport - ${basedir}/src/main/resources/2010/wsdl + com.microsoft.schemas.sharepoint.soap.authentication + ${basedir}/src/main/resources/2010/wsdl authentication.wsdl - /2010/wsdl/authentication.wsdl - com.microsoft.schemas.sharepoint.soap.authentication - - authentication.wsdl - - + alerts2010 generate-sources @@ -50,17 +87,13 @@ wsimport - ${basedir}/src/main/resources/2010/wsdl + com.microsoft.schemas.sharepoint.soap.alerts + ${basedir}/src/main/resources/2010/wsdl alerts.wsdl - /2010/wsdl/alerts.wsdl - com.microsoft.schemas.sharepoint.soap.alerts - - alerts.wsdl - - + sites2010 generate-sources @@ -68,17 +101,13 @@ wsimport + com.microsoft.schemas.sharepoint.soap.sites ${basedir}/src/main/resources/2010/wsdl sites.wsdl - - /2010/wsdl/sites.wsdl - com.microsoft.schemas.sharepoint.soap.sites - - sites.wsdl - + - + webs2010 generate-sources @@ -86,15 +115,11 @@ wsimport - ${basedir}/src/main/resources/2010/wsdl + com.microsoft.schemas.sharepoint.soap.webs + ${basedir}/src/main/resources/2010/wsdl webs.wsdl - /2010/wsdl/webs.wsdl - com.microsoft.schemas.sharepoint.soap.webs - - webs.wsdl - @@ -104,18 +129,75 @@ wsimport + com.microsoft.schemas.sharepoint.soap.lists ${basedir}/src/main/resources/2010/wsdl lists.wsdl - /2010/wsdl/webs.wsdl - com.microsoft.schemas.sharepoint.soap.lists - - lists.wsdl - - - + + + + + + + org.codehaus.mojo + jaxb2-maven-plugin + 1.6 + + + false + false + false + + + + + + batch + + xjc + + + + ${basedir}/src/main/resources/xsd + + batch.xsd + + de.muehlencord.shared.sharepoint.api.batch + + ${project.build.directory}/generated-sources/jaxb/ + true + + ${basedir}/src/main/resources/jaxb + batch.xml + true + + + + + + lists + + xjc + + + + ${basedir}/src/main/resources/xsd + + lists.xsd + + de.muehlencord.shared.sharepoint.api.lists + + ${project.build.directory}/generated-sources/jaxb/ + true + + ${basedir}/src/main/resources/jaxb + lists.xml + true + + + @@ -123,8 +205,17 @@ junit junit - 4.10 test + + org.apache.commons + commons-lang3 + 3.1 + + + ${project.groupId} + shared-util + ${project.version} + \ No newline at end of file diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPContext.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPContext.java index 249b135..44f4be2 100644 --- a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPContext.java +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPContext.java @@ -2,6 +2,12 @@ package de.muehlencord.shared.sharepoint.api; import java.net.Authenticator; import java.net.URL; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; /** * @@ -12,16 +18,52 @@ public class SPContext { private URL siteURL; private AbstractAuthenticator authenticator; private SPVersion spVersion; + private boolean trustAllCerts; - public SPContext(URL siteURL, AbstractAuthenticator authenticator, SPVersion spVersion) { + public SPContext(URL siteURL, AbstractAuthenticator authenticator, SPVersion spVersion) throws NoSuchAlgorithmException, KeyManagementException { this.siteURL = siteURL; this.authenticator = authenticator; this.spVersion = spVersion; + this.trustAllCerts = false; configure(); } - private void configure() { + public SPContext(URL siteURL, AbstractAuthenticator authenticator, SPVersion spVersion, boolean trustAllCerts) throws NoSuchAlgorithmException, KeyManagementException { + this.siteURL = siteURL; + this.authenticator = authenticator; + this.spVersion = spVersion; + this.trustAllCerts = trustAllCerts; + configure(); + } + + private void configure() throws NoSuchAlgorithmException, KeyManagementException { Authenticator.setDefault(authenticator); + // allow SSL connections, even if SSL chain is not complete + // e.g. needed for self signed certificates + // TODO create documentation how to install this cert into the java certificate chain. + if (trustAllCerts) { + // Trust all SSLs, create a trust manager that does not validate certificate chains + TrustManager[] trustManager = new TrustManager[]{new X509TrustManager() { + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + + @Override + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + }}; + // Install the all-trusting trust manager + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustManager, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + } } public URL getSiteURL() { diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPJaxbObject.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPJaxbObject.java new file mode 100644 index 0000000..a9a932e --- /dev/null +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPJaxbObject.java @@ -0,0 +1,161 @@ +/* + * File: $$RCSfile$$ + * + * Copyright (c) 2011 by Wincor Nixdorf, + * Heinz-Nixdorf-Ring 1, 33106 Paderborn, Germany + * + * This software is the confidential and proprietary information + * of Wincor Nixdorf. + * + * You shall not disclose such confidential information and shall + * use it only in accordance with the terms of the license agreement + * you entered into with Wincor Nixdorf. + */ +package de.muehlencord.shared.sharepoint.api; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.List; +import java.util.logging.Level; +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * + * @author joern.muehlencord + */ +public abstract class SPJaxbObject extends SPObject { + + private static JAXBContext jaxbContext = null; + + /** + * list of packages to search in + */ + private static final String packages = "" // + + "de.muehlencord.shared.sharepoint.api.batch" // + + ":de.muehlencord.shared.sharepoint.api.lists"; // + // + ":de.muehlencord.shared.sharepoint.api.sites" // + // + ":com.microsoft.schemas.sharepoint.soap.alerts" // + // + ":com.microsoft.schemas.sharepoint.soap.authentication" // +// + ":com.microsoft.schemas.sharepoint.soap.lists" // +// + ":com.microsoft.schemas.sharepoint.soap.sites" // +// + ":com.microsoft.schemas.sharepoint.soap.webs"; + + public static JAXBContext getJaxbContext() throws JAXBException { + if (jaxbContext == null) { + jaxbContext = JAXBContext.newInstance(packages); + } + return jaxbContext; + } + + protected T value; + protected Class cl; + + public SPJaxbObject(Class cl, SPContext context) throws JAXBException { + super(context); + this.cl = cl; + this.value = null; + } + + protected abstract List getSchemaLocation(); + + protected Schema getSchema() throws SAXException { + List schemaLocations = getSchemaLocation(); + if ((schemaLocations == null) || (schemaLocations.isEmpty())) { + // if instance has no schema available, it is not possible to parse against + return null; + } + + Schema schema; + try { + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + StreamSource[] streamSources = new StreamSource[schemaLocations.size()]; + for (int i = 0; i < schemaLocations.size(); i++) { + String sourceString = schemaLocations.get(i); + InputStream is = SPJaxbObject.class.getResourceAsStream(sourceString); + StreamSource streamSource = new StreamSource(is); + streamSources[i] = streamSource; + } + schema = sf.newSchema(streamSources); + } catch (Exception ex) { + return null; // TODO add error handling + } + return schema; + } + + public void setValue(String valueString) throws JAXBException, SAXException { + SPJaxbObject.getJaxbContext(); + Schema schema = getSchema(); + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + if (schema != null) { + unmarshaller.setSchema(schema); + unmarshaller.setEventHandler(new SPValidationEventHandler()); + } + StringReader reader = new StringReader(valueString); + value = (T) unmarshaller.unmarshal(reader); + } + + public void setValue(T value) { + this.value = value; + } + + public String getValueXmlString() throws JAXBException, SAXException { + SPJaxbObject.getJaxbContext(); + Schema schema = getSchema(); + Marshaller marshaller = jaxbContext.createMarshaller(); + if (schema != null) { + marshaller.setSchema(schema); + marshaller.setEventHandler(new SPValidationEventHandler()); + } + StringWriter writer = new StringWriter(); + marshaller.marshal(getValue(), writer); + + return writer.toString(); + } + + public Node createSharePointCAMLNode() throws ParserConfigurationException, SAXException, IOException, JAXBException { + String xmlString = getValueXmlString(); + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setValidating(false); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = documentBuilder.parse(new InputSource(new StringReader(xmlString))); + Node node = document.getDocumentElement(); + return node; + } + + protected T getValue() { + if (value == null) { + try { + value = cl.newInstance(); + } catch (InstantiationException | IllegalAccessException ex) { + ex.printStackTrace(); + // TODO add logging, correct error handling + return null; + } + } + return value; + } + +} + +/** + * History: + * + * $$Log$$ + * + */ diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPObject.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPObject.java index 22c2262..400651c 100644 --- a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPObject.java +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPObject.java @@ -1,19 +1,60 @@ package de.muehlencord.shared.sharepoint.api; +import java.io.StringWriter; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import org.w3c.dom.Document; + /** * * @author jomu */ -public class SPObject { +public abstract class SPObject { private SPContext context; public SPObject(SPContext context) { this.context = context; } - + public SPContext getContext() { return context; } + /** + * Creates a string from an XML file with start and end indicators + * + * @param docToString document to convert + * @return string of the xml document + */ + public static String xmlToString(Document docToString) { + String returnString = ""; + try { + //create string from xml tree + //Output the XML + //set up a transformer + TransformerFactory transfac = TransformerFactory.newInstance(); + Transformer trans; + trans = transfac.newTransformer(); + trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + trans.setOutputProperty(OutputKeys.INDENT, "yes"); + StringWriter sw = new StringWriter(); + StreamResult streamResult = new StreamResult(sw); + DOMSource source = new DOMSource(docToString); + trans.transform(source, streamResult); + String xmlString = sw.toString(); + //print the XML + returnString = returnString + xmlString; + } catch (TransformerException ex) { + Logger.getLogger(SPObject.class.getName()).log(Level.SEVERE, null, ex); + } + return returnString; + } + } diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPValidationEventHandler.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPValidationEventHandler.java new file mode 100644 index 0000000..70bf50f --- /dev/null +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/SPValidationEventHandler.java @@ -0,0 +1,50 @@ +package de.muehlencord.shared.sharepoint.api; + +import javax.xml.bind.ValidationEvent; +import javax.xml.bind.ValidationEventHandler; + +/** + * + * @author joern.muehlencord + */ +public class SPValidationEventHandler implements ValidationEventHandler { + + @Override + public boolean handleEvent(ValidationEvent event) { + + if (event == null) { + throw new IllegalArgumentException(); + } + + System.out.println("\nEVENT"); + System.out.println("SEVERITY: " + event.getSeverity()); + System.out.println("MESSAGE: " + event.getMessage()); +// System.out.println("LINKED EXCEPTION: " + event.getLinkedException()); + System.out.println("LOCATOR"); + System.out.println(" LINE NUMBER: " + event.getLocator().getLineNumber()); + System.out.println(" COLUMN NUMBER: " + event.getLocator().getColumnNumber()); + System.out.println(" OFFSET: " + event.getLocator().getOffset()); + System.out.println(" OBJECT: " + event.getLocator().getObject()); + System.out.println(" NODE: " + event.getLocator().getNode()); + System.out.println(" URL: " + event.getLocator().getURL()); + + switch (event.getSeverity()) { + case ValidationEvent.WARNING: + return true; // continue after warinings + case ValidationEvent.ERROR: + return false; // terminate after errors + case ValidationEvent.FATAL_ERROR: + return false; // terminate after fatal errors + default: + return false; + } + } + +} + +/** + * History: + * + * $$Log$$ + * + */ diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/ServiceLogHandler.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/ServiceLogHandler.java new file mode 100644 index 0000000..7688cc9 --- /dev/null +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/ServiceLogHandler.java @@ -0,0 +1,66 @@ +package de.muehlencord.shared.sharepoint.api; + +import java.io.IOException; +import java.util.Set; +import javax.xml.namespace.QName; +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPMessage; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPHandler; +import javax.xml.ws.handler.soap.SOAPMessageContext; + +/** + * + * @author joern.muehlencord + */ +public class ServiceLogHandler implements SOAPHandler { + + @Override + public Set getHeaders() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void close(MessageContext arg0) { + // TODO Auto-generated method stub + + } + + @Override + public boolean handleFault(SOAPMessageContext arg0) { + SOAPMessage message = arg0.getMessage(); + try { + message.writeTo(System.out); + } catch (SOAPException | IOException e) { + // TODO add error handling + } + return true; + } + + @Override + public boolean handleMessage(SOAPMessageContext arg0) { + SOAPMessage message = arg0.getMessage(); + boolean isOutboundMessage = (Boolean) arg0.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); + if (isOutboundMessage) { + System.out.println("OUTBOUND MESSAGE\n"); + } else { + System.out.println("INBOUND MESSAGE\n"); + } + try { + message.writeTo(System.out); + System.out.println(); + } catch (SOAPException | IOException e) { + // TODO add error handling + } + return true; + } + +} + +/** + * History: + * + * $$Log$$ + * + */ diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/authentication/SPAuthentication.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/authentication/SPAuthentication.java index 71ed808..385ef94 100644 --- a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/authentication/SPAuthentication.java +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/authentication/SPAuthentication.java @@ -22,12 +22,6 @@ public class SPAuthentication extends SPObject { super(context); } - private void authenticate(BindingProvider prov) throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException { - AbstractAuthenticator authenticator = getContext().getAuthenticator(); - LoginResult result = getAuthenticationPort().login(authenticator.getUserName(), authenticator.getPassword()); - - } - private AuthenticationSoap getAuthenticationPort() throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException { URL wsURL = new URL(getContext().getSiteURL().toString() + "/_vti_bin/Authentication.asmx"); URL wsdlURL = new URL(SPContext.class.getResource("/wsdl/authentication.wsdl").toExternalForm()); @@ -36,5 +30,4 @@ public class SPAuthentication extends SPObject { ((BindingProvider) alertsPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsURL.toString()); return alertsPort; } - } diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPBatch.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPBatch.java new file mode 100644 index 0000000..bdb260d --- /dev/null +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPBatch.java @@ -0,0 +1,39 @@ +package de.muehlencord.shared.sharepoint.api.lists; + +import de.muehlencord.shared.sharepoint.api.SPContext; +import de.muehlencord.shared.sharepoint.api.SPJaxbObject; +import de.muehlencord.shared.sharepoint.api.batch.Batch; +import de.muehlencord.shared.sharepoint.api.batch.Method; +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.JAXBException; + +/** + * + * @author joern.muehlencord + */ +public class SPBatch extends SPJaxbObject { + + public SPBatch(SPContext context) throws JAXBException { + super(Batch.class, context); + } + + @Override + protected List getSchemaLocation() { + List schemaList = new ArrayList(); + schemaList.add("/xsd/batch.xsd"); + return schemaList; + } + + public void addMethod(Method method) { + getValue().getMethods().add(method); + } + +} + +/** + * History: + * + * $$Log$$ + * + */ diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPList.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPList.java index b84c1a9..dacaf07 100644 --- a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPList.java +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPList.java @@ -1,32 +1,176 @@ package de.muehlencord.shared.sharepoint.api.lists; +import com.microsoft.schemas.sharepoint.soap.lists.GetListCollectionResponse; +import com.microsoft.schemas.sharepoint.soap.lists.GetListResponse.GetListResult; import com.microsoft.schemas.sharepoint.soap.lists.Lists; import com.microsoft.schemas.sharepoint.soap.lists.ListsSoap; +import com.microsoft.schemas.sharepoint.soap.lists.UpdateListItems.Updates; import de.muehlencord.shared.sharepoint.api.SPContext; +import de.muehlencord.shared.sharepoint.api.SPJaxbObject; import de.muehlencord.shared.sharepoint.api.SPObject; +import de.muehlencord.shared.sharepoint.api.ServiceLogHandler; +import de.muehlencord.shared.sharepoint.api.batch.Field; +import de.muehlencord.shared.sharepoint.api.batch.Method; +import de.muehlencord.shared.sharepoint.api.batch.MethodType; +import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import javax.xml.bind.JAXBException; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.ws.BindingProvider; +import javax.xml.ws.handler.Handler; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; /** * * @author jomu */ -public class SPList extends SPObject { +public class SPList extends SPJaxbObject { - public SPList(SPContext context) { - super(context); - } + public SPList(SPContext context) throws JAXBException { + super(de.muehlencord.shared.sharepoint.api.lists.Lists.class, context); + } + + @Override + protected List getSchemaLocation() { + List schemaList = new ArrayList(); + schemaList.add("/xsd/lists.xsd"); + return schemaList; + } + + public List getListNames() throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException, ParseException, JAXBException, + SAXException { + if (this.getValue().lists == null) { + getValueFromSharepoint(); + } + List returnList = new LinkedList<>(); + this.getValue().lists.stream(). + forEach((currentList) -> { + returnList.add(currentList.name); + }); + return returnList; + } + + public String getListName(String listTitle) throws NoSuchAlgorithmException, KeyManagementException, JAXBException, MalformedURLException, SAXException { + if (this.getValue().lists == null) { + getValueFromSharepoint(); + } + + for (de.muehlencord.shared.sharepoint.api.lists.List currentList : this.getValue().lists) { + if (currentList.title.equals(listTitle)) { + return currentList.name; + } + } + return null; + } + + public void getListColumns(String listName) throws NoSuchAlgorithmException, KeyManagementException, JAXBException, MalformedURLException, SAXException { + GetListResult result = getListsPort(getContext().getSiteURL()).getList(listName); + + if (result.getContent() != null) { + for (Object content : result.getContent()) { + // TODO - handdling more than one result / should not occur + if (content instanceof Element) { + // Parse XML file + Element rootElement = (Element) content; + String listsString = SPObject.xmlToString(rootElement.getOwnerDocument()); + System.out.println (listsString); + // TODO implement handling + // this.setValue(listsString); + } + } + } + } + + public void addListItem(String listName, Map data) throws NoSuchAlgorithmException, KeyManagementException, JAXBException, + MalformedURLException, SAXException, ParserConfigurationException, IOException { + List> dataList = new LinkedList<>(); + dataList.add(data); + addListItems(listName, dataList); + } + + public void addListItemByTitle(String listTitle, Map data) throws NoSuchAlgorithmException, KeyManagementException, JAXBException, + MalformedURLException, SAXException, ParserConfigurationException, IOException { + List> dataList = new LinkedList<>(); + dataList.add(data); + addListItems(getListName(listTitle), dataList); + } + + public void addListItems(String listName, List> dataList) throws NoSuchAlgorithmException, KeyManagementException, JAXBException, + MalformedURLException, SAXException, ParserConfigurationException, IOException { + if (this.getValue().lists == null) { + getValueFromSharepoint(); + } + + // prepare batch to be posted to sharepoint server + SPBatch batch = new SPBatch(getContext()); + for (Integer batchId = 1; batchId <= dataList.size(); batchId++) { + Method method = new Method(); + method.setID(batchId); + method.setCmd(MethodType.NEW); + Map data = dataList.get(batchId - 1); + data.keySet().stream(). + map((key) -> { + Field field = new Field(); + field.setName(key); + field.setContent(data.get(key)); + return field; + }). + forEach((field) -> { + method.getFields().add(field); + }); + batch.addMethod(method); + } + + // convert batch to node and attach it to update to be executed + Updates updates = new Updates(); + String batchXML = batch.getValueXmlString(); + System.out.println(batchXML); + Node node = batch.createSharePointCAMLNode(); + updates.getContent().add(node); + + // use created update object to execute on sharepoint + getListsPort(getContext().getSiteURL()).updateListItems(listName, updates); + } private ListsSoap getListsPort(URL webUrl) throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException { URL wsURL = new URL(webUrl.toString() + "/_vti_bin/Lists.asmx"); - URL wsdlURL = new URL(SPContext.class.getResource("/wsdl/lists.wsdl").toExternalForm()); + URL wsdlURL = new URL(SPContext.class.getResource("/2010/wsdl/lists.wsdl").toExternalForm()); Lists service = new Lists(wsdlURL); ListsSoap listsPort = service.getListsSoap(); ((BindingProvider) listsPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsURL.toString()); + + // log all incoming and outgoing communication - TODO make this configurable by DEBUG switch + java.util.List handlers = ((BindingProvider) listsPort).getBinding().getHandlerChain(); + handlers.add(new ServiceLogHandler()); + ((BindingProvider) listsPort).getBinding().setHandlerChain(handlers); + return listsPort; } + private void getValueFromSharepoint() throws NoSuchAlgorithmException, KeyManagementException, JAXBException, MalformedURLException, SAXException { + GetListCollectionResponse.GetListCollectionResult result = getListsPort(getContext().getSiteURL()).getListCollection(); + + if (result.getContent() != null) { + for (Object content : result.getContent()) { + // TODO - handdling more than one result / should not occur + if (content instanceof Element) { + // Parse XML file + Element rootElement = (Element) content; + String listsString = SPObject.xmlToString(rootElement.getOwnerDocument()); + this.setValue(listsString); + } + } + } + } + } diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPMethod.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPMethod.java new file mode 100644 index 0000000..9f32af5 --- /dev/null +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/lists/SPMethod.java @@ -0,0 +1,48 @@ +package de.muehlencord.shared.sharepoint.api.lists; + +import de.muehlencord.shared.sharepoint.api.SPContext; +import de.muehlencord.shared.sharepoint.api.SPJaxbObject; +import de.muehlencord.shared.sharepoint.api.batch.Field; +import de.muehlencord.shared.sharepoint.api.batch.Method; +import de.muehlencord.shared.sharepoint.api.batch.MethodType; +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.JAXBException; + +/** + * + * @author joern.muehlencord + */ +public class SPMethod extends SPJaxbObject { + + public SPMethod(SPContext context) throws JAXBException { + super(Method.class, context); + } + + @Override + protected List getSchemaLocation() { + List schemaList = new ArrayList(); + schemaList.add("/xsd/batch.xsd"); + return schemaList; + } + + public void setID(Integer batchId) { + getValue().setID(batchId); + } + + public void setCmd(MethodType methodType) { + getValue().setCmd(methodType); + } + + public List getFields() { + return getValue().getFields(); + } + +} + +/** + * History: + * + * $$Log$$ + * + */ diff --git a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/sites/SPSite.java b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/sites/SPSite.java index 7d9cd94..1c29c17 100644 --- a/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/sites/SPSite.java +++ b/sharepoint/api/src/main/java/de/muehlencord/shared/sharepoint/api/sites/SPSite.java @@ -1,5 +1,6 @@ package de.muehlencord.shared.sharepoint.api.sites; +import com.microsoft.schemas.sharepoint.soap.webs.GetWebResponse; import com.microsoft.schemas.sharepoint.soap.webs.Webs; import com.microsoft.schemas.sharepoint.soap.webs.WebsSoap; import de.muehlencord.shared.sharepoint.api.SPContext; @@ -9,6 +10,7 @@ import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.xml.ws.BindingProvider; +import org.apache.commons.lang3.StringUtils; /** * @@ -19,13 +21,19 @@ public class SPSite extends SPObject { public SPSite(SPContext context) { super(context); } - - public static WebsSoap getWebsPort(URL webUrl) throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException { + + public void getRootWeb() throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException { + String rootWebUrl = StringUtils.removeEndIgnoreCase(getContext().getSiteURL().toString(), "/"); + GetWebResponse.GetWebResult result = getWebsPort(getContext().getSiteURL()).getWeb(rootWebUrl); + System.out.println (result); + } + + private WebsSoap getWebsPort(URL webUrl) throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException { URL wsURL = new URL(webUrl.toString() + "/_vti_bin/Webs.asmx"); - URL wsdlURL = new URL(SPSite.class.getResource("/wsdl/webs.wsdl").toExternalForm()); + URL wsdlURL = new URL(SPSite.class.getResource("/2010/wsdl/webs.wsdl").toExternalForm()); Webs service = new Webs(wsdlURL); WebsSoap websPort = service.getWebsSoap(); ((BindingProvider) websPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsURL.toString()); return websPort; - } + } } diff --git a/sharepoint/api/src/main/resources/jaxb/batch.xml b/sharepoint/api/src/main/resources/jaxb/batch.xml new file mode 100644 index 0000000..6190c27 --- /dev/null +++ b/sharepoint/api/src/main/resources/jaxb/batch.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/sharepoint/api/src/main/resources/jaxb/lists.xml b/sharepoint/api/src/main/resources/jaxb/lists.xml new file mode 100644 index 0000000..5177d7a --- /dev/null +++ b/sharepoint/api/src/main/resources/jaxb/lists.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/sharepoint/api/src/main/resources/xsd/batch.xsd b/sharepoint/api/src/main/resources/xsd/batch.xsd new file mode 100644 index 0000000..634bea7 --- /dev/null +++ b/sharepoint/api/src/main/resources/xsd/batch.xsd @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sharepoint/api/src/main/resources/xsd/lists.xsd b/sharepoint/api/src/main/resources/xsd/lists.xsd new file mode 100644 index 0000000..f1d89f8 --- /dev/null +++ b/sharepoint/api/src/main/resources/xsd/lists.xsd @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sharepoint/api/src/test/java/de/muehlencord/shared/sharepoint/api/lists/SPListTest.java b/sharepoint/api/src/test/java/de/muehlencord/shared/sharepoint/api/lists/SPListTest.java new file mode 100644 index 0000000..888fab4 --- /dev/null +++ b/sharepoint/api/src/test/java/de/muehlencord/shared/sharepoint/api/lists/SPListTest.java @@ -0,0 +1,75 @@ +package de.muehlencord.shared.sharepoint.api.lists; + +import de.muehlencord.shared.sharepoint.api.NtlmAuthenticator; +import de.muehlencord.shared.sharepoint.api.SPContext; +import de.muehlencord.shared.sharepoint.api.SPVersion; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; +import javax.xml.bind.JAXBException; +import javax.xml.parsers.ParserConfigurationException; +import org.junit.Test; +import org.xml.sax.SAXException; + +/** + * + * @author joern.muehlencord + */ +public class SPListTest { + + public SPListTest() { + } + + @Test + public void testSPList() throws MalformedURLException, NoSuchAlgorithmException, KeyManagementException, ParseException, JAXBException, SAXException, + ParserConfigurationException, IOException { + // Create NTLM v2 credentials (authenticator) & setup context + + // FIXME - needs to be implemented using mock; replace with real data but make sure password is not commited + NtlmAuthenticator credentials = null; + SPContext context = null; + // Connect to Sharepoint + // SPSite instance = new SPSite(context); + SPList instance = new SPList(context); + // System.out.println (instance.getListNames()); + // System.out.println (instance.getListName("Test")); + // instance.getListColumns(instance.getListName("Questionnaire Test")); + +// Map data = new HashMap<>(); +// data.put("Country", "DE"); +// data.put("WNRegion", "DACH"); +// data.put("AccountManager", "Jörn"); +// data.put("Customer", "Mühlencord"); +// data.put("Current OS", "Windows XP"); +// data.put("PlannedOS", "migrate to Windows 7"); +// data.put("RolloutStart", "in 2014"); +// data.put("RolloutEnd", "in 2015"); +// data.put("InstalledBase", "2000"); +// data.put("IbaseMigrated", "1000"); +// data.put("IbaseOrdered", "500"); +// data.put("IbaseNotOrdered", "500"); +// data.put("IbaseNotMigrated", "0"); +// data.put("ReaseonNotMigrated", ""); +// data.put("Platform", "ProBase/C"); +// data.put("IbaseOldPlatform", "0"); +// data.put("Application", "ProFlex4"); +// data.put("IbaseOldApplication", "0"); +// data.put("MaintenanceContract", "none"); +// data.put("Comments", "This is a test"); +// instance.addListItemByTitle("Questionnaire Test", data); + + Map data = new HashMap<>(); + data.put ("Title", "Test"); + data.put ("Choice", "Enter Choice #1"); // is not check, possible to add wrong value + // data.put ("Country", "DE"); // reference needed, need to implement lookup + data.put ("Number", "17"); // is validating + data.put ("Lines", "Long text
with line breaks"); // line breaks using
+ instance.addListItemByTitle("Test", data); + } + +} diff --git a/sharepoint/api/src/test/resources/BatchImportTest.xml b/sharepoint/api/src/test/resources/BatchImportTest.xml new file mode 100644 index 0000000..eec1f87 --- /dev/null +++ b/sharepoint/api/src/test/resources/BatchImportTest.xml @@ -0,0 +1,17 @@ + + + + 6 + Modified sixth item + + + 7 + Modified seventh item + + + 5 + + + Added item + + \ No newline at end of file diff --git a/sharepoint/api/src/test/resources/BatchTest.xml b/sharepoint/api/src/test/resources/BatchTest.xml new file mode 100644 index 0000000..0a040b4 --- /dev/null +++ b/sharepoint/api/src/test/resources/BatchTest.xml @@ -0,0 +1,17 @@ + + + + 6 + Modified sixth item + + + 7 + Modified seventh item + + + 5 + + + Added item + + \ No newline at end of file diff --git a/sharepoint/pom.xml b/sharepoint/pom.xml index 60cc78b..99a8907 100644 --- a/sharepoint/pom.xml +++ b/sharepoint/pom.xml @@ -7,7 +7,7 @@ 1.0-SNAPSHOT de.muehlencord.shared - sharepoint + shared-sharepoint pom api