implemented first basic lists handling functions

This commit is contained in:
jomu
2015-02-02 18:41:01 +00:00
parent e81182ae47
commit f96e4e4a39
19 changed files with 998 additions and 66 deletions

View File

@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>de.muehlencord.shared</groupId> <groupId>de.muehlencord.shared</groupId>
<artifactId>sharepoint</artifactId> <artifactId>shared-sharepoint</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</parent> </parent>
@ -14,11 +15,51 @@
<build> <build>
<plugins> <plugins>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
-->
<!-- project overall settings -->
<plugin>
<!-- Ensure that usage of the maven-jaxb2-plugin is JDK 8 compatible in absence of a fix
for https://java.net/jira/browse/MAVEN_JAXB2_PLUGIN-80.
TODO: bug is fixed, but how to apply to xsd generation plugin-->
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<id>set-additional-system-properties</id>
<goals>
<goal>set-system-properties</goal>
</goals>
</execution>
</executions>
<configuration>
<properties>
<property>
<name>javax.xml.accessExternalSchema</name>
<value>file,http</value>
</property>
</properties>
</configuration>
</plugin>
<!-- convert wsdl to object -->
<plugin> <plugin>
<groupId>org.jvnet.jax-ws-commons</groupId> <groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId> <artifactId>jaxws-maven-plugin</artifactId>
<version>2.2</version> <version>2.2</version> <!-- TODO does not work with 2.3 -->
<configuration> <configuration>
<sourceDestDir>${project.build.directory}/generated-sources/jaxws-wsimport</sourceDestDir> <sourceDestDir>${project.build.directory}/generated-sources/jaxws-wsimport</sourceDestDir>
@ -32,12 +73,8 @@
<goal>wsimport</goal> <goal>wsimport</goal>
</goals> </goals>
<configuration> <configuration>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>authentication.wsdl</wsdlFile>
</wsdlFiles>
<wsdlLocation>/2010/wsdl/authentication.wsdl</wsdlLocation>
<packageName>com.microsoft.schemas.sharepoint.soap.authentication</packageName> <packageName>com.microsoft.schemas.sharepoint.soap.authentication</packageName>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles> <wsdlFiles>
<wsdlFile>authentication.wsdl</wsdlFile> <wsdlFile>authentication.wsdl</wsdlFile>
</wsdlFiles> </wsdlFiles>
@ -50,12 +87,8 @@
<goal>wsimport</goal> <goal>wsimport</goal>
</goals> </goals>
<configuration> <configuration>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>alerts.wsdl</wsdlFile>
</wsdlFiles>
<wsdlLocation>/2010/wsdl/alerts.wsdl</wsdlLocation>
<packageName>com.microsoft.schemas.sharepoint.soap.alerts</packageName> <packageName>com.microsoft.schemas.sharepoint.soap.alerts</packageName>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles> <wsdlFiles>
<wsdlFile>alerts.wsdl</wsdlFile> <wsdlFile>alerts.wsdl</wsdlFile>
</wsdlFiles> </wsdlFiles>
@ -68,12 +101,8 @@
<goal>wsimport</goal> <goal>wsimport</goal>
</goals> </goals>
<configuration> <configuration>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>sites.wsdl</wsdlFile>
</wsdlFiles>
<wsdlLocation>/2010/wsdl/sites.wsdl</wsdlLocation>
<packageName>com.microsoft.schemas.sharepoint.soap.sites</packageName> <packageName>com.microsoft.schemas.sharepoint.soap.sites</packageName>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles> <wsdlFiles>
<wsdlFile>sites.wsdl</wsdlFile> <wsdlFile>sites.wsdl</wsdlFile>
</wsdlFiles> </wsdlFiles>
@ -86,12 +115,8 @@
<goal>wsimport</goal> <goal>wsimport</goal>
</goals> </goals>
<configuration> <configuration>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>webs.wsdl</wsdlFile>
</wsdlFiles>
<wsdlLocation>/2010/wsdl/webs.wsdl</wsdlLocation>
<packageName>com.microsoft.schemas.sharepoint.soap.webs</packageName> <packageName>com.microsoft.schemas.sharepoint.soap.webs</packageName>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles> <wsdlFiles>
<wsdlFile>webs.wsdl</wsdlFile> <wsdlFile>webs.wsdl</wsdlFile>
</wsdlFiles> </wsdlFiles>
@ -104,15 +129,72 @@
<goal>wsimport</goal> <goal>wsimport</goal>
</goals> </goals>
<configuration> <configuration>
<packageName>com.microsoft.schemas.sharepoint.soap.lists</packageName>
<wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory> <wsdlDirectory>${basedir}/src/main/resources/2010/wsdl</wsdlDirectory>
<wsdlFiles> <wsdlFiles>
<wsdlFile>lists.wsdl</wsdlFile> <wsdlFile>lists.wsdl</wsdlFile>
</wsdlFiles> </wsdlFiles>
<wsdlLocation>/2010/wsdl/webs.wsdl</wsdlLocation> </configuration>
<packageName>com.microsoft.schemas.sharepoint.soap.lists</packageName> </execution>
<wsdlFiles> </executions>
<wsdlFile>lists.wsdl</wsdlFile> </plugin>
</wsdlFiles>
<!-- Maven jaxb2 plugin - invoke the xjc compiler to compile XML schema into Java classes. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<quiet>false</quiet>
<verbose>false</verbose>
<clearOutputDir>false</clearOutputDir> <!-- do not set to true, multiple executions into same dir -->
</configuration>
<executions>
<!-- sharepoint batch definition for updating lists etc. -->
<execution>
<id>batch</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<!-- The schema directory or xsd files. -->
<schemaDirectory>${basedir}/src/main/resources/xsd</schemaDirectory>
<!-- the file to read -->
<schemaFiles>batch.xsd</schemaFiles>
<!-- The package in which the source files will be generated. -->
<packageName>de.muehlencord.shared.sharepoint.api.batch</packageName>
<!-- The working directory to create the generated java source files. -->
<outputDirectory>${project.build.directory}/generated-sources/jaxb/</outputDirectory>
<removeOldOutput>true</removeOldOutput>
<!-- bindings to use -->
<bindingDirectory>${basedir}/src/main/resources/jaxb</bindingDirectory>
<bindingFiles>batch.xml</bindingFiles>
<extension>true</extension>
</configuration>
</execution>
<!-- lists definition, returned by sharepoint when execute a query on a lists -->
<execution>
<id>lists</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<!-- The schema directory or xsd files. -->
<schemaDirectory>${basedir}/src/main/resources/xsd</schemaDirectory>
<!-- the file to read -->
<schemaFiles>lists.xsd</schemaFiles>
<!-- The package in which the source files will be generated. -->
<packageName>de.muehlencord.shared.sharepoint.api.lists</packageName>
<!-- The working directory to create the generated java source files. -->
<outputDirectory>${project.build.directory}/generated-sources/jaxb/</outputDirectory>
<removeOldOutput>true</removeOldOutput>
<!-- bindings to use -->
<bindingDirectory>${basedir}/src/main/resources/jaxb</bindingDirectory>
<bindingFiles>lists.xml</bindingFiles>
<extension>true</extension>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
@ -123,8 +205,17 @@
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>shared-util</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -2,6 +2,12 @@ package de.muehlencord.shared.sharepoint.api;
import java.net.Authenticator; import java.net.Authenticator;
import java.net.URL; 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 URL siteURL;
private AbstractAuthenticator authenticator; private AbstractAuthenticator authenticator;
private SPVersion spVersion; 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.siteURL = siteURL;
this.authenticator = authenticator; this.authenticator = authenticator;
this.spVersion = spVersion; this.spVersion = spVersion;
this.trustAllCerts = false;
configure(); 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); 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() { public URL getSiteURL() {

View File

@ -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<T> 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<T> cl;
public SPJaxbObject(Class<T> cl, SPContext context) throws JAXBException {
super(context);
this.cl = cl;
this.value = null;
}
protected abstract List<String> getSchemaLocation();
protected Schema getSchema() throws SAXException {
List<String> 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$$
*
*/

View File

@ -1,10 +1,21 @@
package de.muehlencord.shared.sharepoint.api; 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 * @author jomu
*/ */
public class SPObject { public abstract class SPObject {
private SPContext context; private SPContext context;
@ -16,4 +27,34 @@ public class SPObject {
return context; 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;
}
} }

View File

@ -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$$
*
*/

View File

@ -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<SOAPMessageContext> {
@Override
public Set<QName> 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$$
*
*/

View File

@ -22,12 +22,6 @@ public class SPAuthentication extends SPObject {
super(context); 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 { private AuthenticationSoap getAuthenticationPort() throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException {
URL wsURL = new URL(getContext().getSiteURL().toString() + "/_vti_bin/Authentication.asmx"); URL wsURL = new URL(getContext().getSiteURL().toString() + "/_vti_bin/Authentication.asmx");
URL wsdlURL = new URL(SPContext.class.getResource("/wsdl/authentication.wsdl").toExternalForm()); 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()); ((BindingProvider) alertsPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsURL.toString());
return alertsPort; return alertsPort;
} }
} }

View File

@ -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<Batch> {
public SPBatch(SPContext context) throws JAXBException {
super(Batch.class, context);
}
@Override
protected List getSchemaLocation() {
List<String> schemaList = new ArrayList();
schemaList.add("/xsd/batch.xsd");
return schemaList;
}
public void addMethod(Method method) {
getValue().getMethods().add(method);
}
}
/**
* History:
*
* $$Log$$
*
*/

View File

@ -1,32 +1,176 @@
package de.muehlencord.shared.sharepoint.api.lists; 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.Lists;
import com.microsoft.schemas.sharepoint.soap.lists.ListsSoap; 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.SPContext;
import de.muehlencord.shared.sharepoint.api.SPJaxbObject;
import de.muehlencord.shared.sharepoint.api.SPObject; 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.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; 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.BindingProvider;
import javax.xml.ws.handler.Handler;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
/** /**
* *
* @author jomu * @author jomu
*/ */
public class SPList extends SPObject { public class SPList extends SPJaxbObject<de.muehlencord.shared.sharepoint.api.lists.Lists> {
public SPList(SPContext context) { public SPList(SPContext context) throws JAXBException {
super(context); super(de.muehlencord.shared.sharepoint.api.lists.Lists.class, context);
}
@Override
protected List getSchemaLocation() {
List<String> schemaList = new ArrayList();
schemaList.add("/xsd/lists.xsd");
return schemaList;
}
public List<String> getListNames() throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException, ParseException, JAXBException,
SAXException {
if (this.getValue().lists == null) {
getValueFromSharepoint();
}
List<String> 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<String, String> data) throws NoSuchAlgorithmException, KeyManagementException, JAXBException,
MalformedURLException, SAXException, ParserConfigurationException, IOException {
List<Map<String, String>> dataList = new LinkedList<>();
dataList.add(data);
addListItems(listName, dataList);
}
public void addListItemByTitle(String listTitle, Map<String, String> data) throws NoSuchAlgorithmException, KeyManagementException, JAXBException,
MalformedURLException, SAXException, ParserConfigurationException, IOException {
List<Map<String, String>> dataList = new LinkedList<>();
dataList.add(data);
addListItems(getListName(listTitle), dataList);
}
public void addListItems(String listName, List<Map<String, String>> 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<String, String> 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 { private ListsSoap getListsPort(URL webUrl) throws NoSuchAlgorithmException, KeyManagementException, MalformedURLException {
URL wsURL = new URL(webUrl.toString() + "/_vti_bin/Lists.asmx"); 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); Lists service = new Lists(wsdlURL);
ListsSoap listsPort = service.getListsSoap(); ListsSoap listsPort = service.getListsSoap();
((BindingProvider) listsPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsURL.toString()); ((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<Handler> handlers = ((BindingProvider) listsPort).getBinding().getHandlerChain();
handlers.add(new ServiceLogHandler());
((BindingProvider) listsPort).getBinding().setHandlerChain(handlers);
return listsPort; 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);
}
}
}
}
} }

View File

@ -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<Method> {
public SPMethod(SPContext context) throws JAXBException {
super(Method.class, context);
}
@Override
protected List getSchemaLocation() {
List<String> 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<Field> getFields() {
return getValue().getFields();
}
}
/**
* History:
*
* $$Log$$
*
*/

View File

@ -1,5 +1,6 @@
package de.muehlencord.shared.sharepoint.api.sites; 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.Webs;
import com.microsoft.schemas.sharepoint.soap.webs.WebsSoap; import com.microsoft.schemas.sharepoint.soap.webs.WebsSoap;
import de.muehlencord.shared.sharepoint.api.SPContext; import de.muehlencord.shared.sharepoint.api.SPContext;
@ -9,6 +10,7 @@ import java.net.URL;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import javax.xml.ws.BindingProvider; import javax.xml.ws.BindingProvider;
import org.apache.commons.lang3.StringUtils;
/** /**
* *
@ -20,9 +22,15 @@ public class SPSite extends SPObject {
super(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 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); Webs service = new Webs(wsdlURL);
WebsSoap websPort = service.getWebsSoap(); WebsSoap websPort = service.getWebsSoap();
((BindingProvider) websPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsURL.toString()); ((BindingProvider) websPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsURL.toString());

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="../xsd/batch.xsd"
node="/xs:schema">
<jxb:globalBindings>
<xjc:simple />
<xjc:serializable uid="100" />
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="../xsd/lists.xsd"
node="/xs:schema">
<jxb:globalBindings>
<xjc:simple />
<xjc:serializable uid="100" />
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Batch">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="Method" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Method">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="Field" />
</xs:sequence>
<xs:attribute name="Cmd" use="required" type="MethodType" />
<xs:attribute name="ID" use="required" type="xs:int" />
</xs:complexType>
</xs:element>
<xs:element name="Field">
<xs:complexType mixed="true">
<xs:attribute name="Name" use="required" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:simpleType name="MethodType">
<xs:restriction base="xs:string">
<xs:enumeration value="New" />
<xs:enumeration value="Update" />
<xs:enumeration value="Move" />
<xs:enumeration value="Delete" />
</xs:restriction>
</xs:simpleType>
</xs:schema>

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/sharepoint/soap/" xmlns:soap="http://schemas.microsoft.com/sharepoint/soap/">
<xs:element name="Lists">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="soap:List"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="List">
<xs:complexType>
<xs:attribute name="AllowDeletion" use="required" type="xs:NCName"/>
<xs:attribute name="AllowMultiResponses" use="required" type="xs:NCName"/>
<xs:attribute name="AnonymousPermMask" use="required" type="xs:integer"/>
<xs:attribute name="Author" use="required" type="xs:integer"/>
<xs:attribute name="BaseType" use="required" type="xs:integer"/>
<xs:attribute name="CanOpenFileAsync" use="required" type="xs:NCName"/>
<xs:attribute name="Created" use="required"/>
<xs:attribute name="DefaultViewUrl" use="required"/>
<xs:attribute name="Description" use="required"/>
<xs:attribute name="Direction" use="required" type="xs:NCName"/>
<xs:attribute name="DocTemplateUrl" use="required"/>
<xs:attribute name="EmailAlias" use="required"/>
<xs:attribute name="EnableAttachments" use="required" type="xs:NCName"/>
<xs:attribute name="EnableFolderCreation" use="required" type="xs:NCName"/>
<xs:attribute name="EnableMinorVersion" use="required" type="xs:NCName"/>
<xs:attribute name="EnableModeration" use="required" type="xs:NCName"/>
<xs:attribute name="EnablePeopleSelector" use="required" type="xs:NCName"/>
<xs:attribute name="EnableResourceSelector" use="required" type="xs:NCName"/>
<xs:attribute name="EnableVersioning" use="required" type="xs:NCName"/>
<xs:attribute name="EnforceDataValidation" use="required" type="xs:NCName"/>
<xs:attribute name="EventSinkAssembly" use="required"/>
<xs:attribute name="EventSinkClass" use="required"/>
<xs:attribute name="EventSinkData" use="required"/>
<xs:attribute name="ExcludeFromOfflineClient" use="required" type="xs:NCName"/>
<xs:attribute name="FeatureId" use="required"/>
<xs:attribute name="Flags" use="required" type="xs:integer"/>
<xs:attribute name="Followable" use="required" type="xs:NCName"/>
<xs:attribute name="HasExternalDataSource" use="required" type="xs:NCName"/>
<xs:attribute name="HasRelatedLists" use="required"/>
<xs:attribute name="HasUniqueScopes" use="required" type="xs:NCName"/>
<xs:attribute name="Hidden" use="required" type="xs:NCName"/>
<xs:attribute name="ID" use="required"/>
<xs:attribute name="ImageUrl" use="required"/>
<xs:attribute name="IrmEnabled" use="required" type="xs:NCName"/>
<xs:attribute name="IsApplicationList" use="required" type="xs:NCName"/>
<xs:attribute name="ItemCount" use="required" type="xs:integer"/>
<xs:attribute name="LastDeleted" use="required"/>
<xs:attribute name="MajorVersionLimit" use="required" type="xs:integer"/>
<xs:attribute name="MajorWithMinorVersionsLimit" use="required" type="xs:integer"/>
<xs:attribute name="MaxItemsPerThrottledOperation" use="required" type="xs:integer"/>
<xs:attribute name="MobileDefaultViewUrl" use="required"/>
<xs:attribute name="Modified" use="required"/>
<xs:attribute name="MultipleDataList" use="required" type="xs:NCName"/>
<xs:attribute name="Name" use="required"/>
<xs:attribute name="NoThrottleListOperations" use="required" type="xs:NCName"/>
<xs:attribute name="Ordered" use="required" type="xs:NCName"/>
<xs:attribute name="PreserveEmptyValues" use="required" type="xs:NCName"/>
<xs:attribute name="ReadSecurity" use="required" type="xs:integer"/>
<xs:attribute name="RequireCheckout" use="required" type="xs:NCName"/>
<xs:attribute name="RootFolder" use="required"/>
<xs:attribute name="ScopeId" use="required"/>
<xs:attribute name="SendToLocation" use="required"/>
<xs:attribute name="ServerTemplate" use="required" type="xs:integer"/>
<xs:attribute name="ShowUser" use="required" type="xs:NCName"/>
<xs:attribute name="StrictTypeCoercion" use="required" type="xs:NCName"/>
<xs:attribute name="ThrottleListOperations" use="required" type="xs:NCName"/>
<xs:attribute name="ThumbnailSize" use="required"/>
<xs:attribute name="Title" use="required"/>
<xs:attribute name="Version" use="required" type="xs:integer"/>
<xs:attribute name="WebFullUrl" use="required"/>
<xs:attribute name="WebId" use="required"/>
<xs:attribute name="WebImageHeight" use="required"/>
<xs:attribute name="WebImageWidth" use="required"/>
<xs:attribute name="WorkFlowId" use="required"/>
<xs:attribute name="WriteSecurity" use="required" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -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<String, String> 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<String, String> 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<br>with line breaks"); // line breaks using <br>
instance.addListItemByTitle("Test", data);
}
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<Batch>
<Method ID="1" Cmd="Update">
<Field Name="ID">6</Field>
<Field Name="Title">Modified sixth item</Field>
</Method>
<Method ID="2" Cmd="Update">
<Field Name="ID">7</Field>
<Field Name="Title">Modified seventh item</Field>
</Method>
<Method ID="3" Cmd="Delete">
<Field Name="ID">5</Field>
</Method>
<Method ID="4" Cmd="New">
<Field Name="Title">Added item</Field>
</Method>
</Batch>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<Batch xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation='../../main/resources/xsd/batch.xsd'>
<Method ID="1" Cmd="Update">
<Field Name="ID">6</Field>
<Field Name="Title">Modified sixth item</Field>
</Method>
<Method ID="2" Cmd="Update">
<Field Name="ID">7</Field>
<Field Name="Title">Modified seventh item</Field>
</Method>
<Method ID="3" Cmd="Delete">
<Field Name="ID">5</Field>
</Method>
<Method ID="4" Cmd="New">
<Field Name="Title">Added item</Field>
</Method>
</Batch>

View File

@ -7,7 +7,7 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</parent> </parent>
<groupId>de.muehlencord.shared</groupId> <groupId>de.muehlencord.shared</groupId>
<artifactId>sharepoint</artifactId> <artifactId>shared-sharepoint</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
<module>api</module> <module>api</module>