initial commit for export
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d2c0692
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.classpath
+.project
+target/
+credentials
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..dc51487
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,96 @@
+<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>
+  <groupId>com.google.gwt.site</groupId>
+  <artifactId>uploader</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  
+  <dependencies>
+  	<dependency>
+	  	<groupId>com.google.gwt.site</groupId>
+		<artifactId>docs-markdown</artifactId>
+		<version>1.0-SNAPSHOT</version>
+		<type>zip</type>
+		<classifier>generated_docs</classifier>
+  	</dependency>
+  	<dependency>
+		<groupId>commons-httpclient</groupId>
+		<artifactId>commons-httpclient</artifactId>
+		<version>3.1</version>
+	</dependency>
+   <dependency>
+			<groupId>com.google.appengine</groupId>
+			<artifactId>appengine-api-1.0-sdk</artifactId>
+			<version>1.7.6</version>
+		</dependency>
+		
+		<dependency>
+	<groupId>com.google.appengine</groupId>
+	<artifactId>appengine-tools-sdk</artifactId>
+	<version>1.7.6</version>
+</dependency>
+
+<dependency>
+   <groupId>com.google.appengine</groupId>
+   <artifactId>appengine-remote-api</artifactId>
+   <version>1.6.1</version>
+</dependency>
+  </dependencies>  
+  <build>
+    <plugins>
+    <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <version>2.5.1</version>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+    
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.7</version>
+        <executions>
+          <execution>
+            <id>unpack-dependencies</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>unpack-dependencies</goal>
+            </goals>
+            <configuration>
+            	<includeGroupIds>com.google.gwt.site</includeGroupIds>
+          		<includeArtifactIds>docs-markdown</includeArtifactIds>
+          		<outputDirectory>${project.build.directory}/markdown-unpack</outputDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      
+    	<plugin>
+
+		<groupId>org.codehaus.mojo</groupId>
+		<artifactId>exec-maven-plugin</artifactId>
+		<version>1.1.1</version>
+		<executions>
+			<execution>
+				<phase>prepare-package</phase>
+				<goals>
+					<goal>java</goal>
+				</goals>
+				<configuration>
+					<mainClass>com.google.gwt.site.uploader.Uploader</mainClass>
+					<arguments>
+						<argument>${project.build.directory}/markdown-unpack</argument>
+						<argument>${basedir}/credentials</argument>
+					</arguments>
+				</configuration>
+			</execution>
+		</executions>
+	</plugin>
+      
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/src/main/java/com/google/gwt/site/uploader/Credentials.java b/src/main/java/com/google/gwt/site/uploader/Credentials.java
new file mode 100644
index 0000000..8920c37
--- /dev/null
+++ b/src/main/java/com/google/gwt/site/uploader/Credentials.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013 Daniel Kurka
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.site.uploader;
+
+public class Credentials {
+
+  private String host;
+  private String username;
+  private String password;
+
+  public Credentials(String host, String username, String password) {
+    this.host = host;
+    this.username = username;
+    this.password = password;
+
+  }
+
+  public String getHost() {
+    return host;
+  }
+
+  public String getUsername() {
+    return username;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+}
diff --git a/src/main/java/com/google/gwt/site/uploader/FileTraverser.java b/src/main/java/com/google/gwt/site/uploader/FileTraverser.java
new file mode 100644
index 0000000..1370913
--- /dev/null
+++ b/src/main/java/com/google/gwt/site/uploader/FileTraverser.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2013 Daniel Kurka
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.site.uploader;
+
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
+
+public class FileTraverser {
+	List<MarkdownFile> markdownFiles = new LinkedList<MarkdownFile>();
+	private final String filesDir;
+
+	public FileTraverser(String filesDir) {
+		this.filesDir = filesDir;
+
+	}
+
+	public List<MarkdownFile> traverse(String path) {
+
+		File file = new File(path);
+		if (file.isDirectory()) {
+
+			System.out.println("dir found: " + path);
+			File[] listFiles = file.listFiles();
+			for (File f : listFiles) {
+				traverse(f.getPath());
+			}
+		} else if (file.isFile() && shouldFileBeUploaded(file.getName())) {
+
+			markdownFiles
+					.add(new MarkdownFile(path.replace(filesDir, ""), file));
+			System.out.println("file found: " + path);
+
+		}
+		return markdownFiles;
+	}
+
+	private boolean shouldFileBeUploaded(String fileName) {
+		return fileName.endsWith(".html") || fileName.endsWith(".css")
+				|| fileName.endsWith(".js") || fileName.endsWith(".png")
+				|| fileName.endsWith(".jpg") || fileName.endsWith(".gif");
+	}
+
+}
diff --git a/src/main/java/com/google/gwt/site/uploader/MarkdownFile.java b/src/main/java/com/google/gwt/site/uploader/MarkdownFile.java
new file mode 100644
index 0000000..c66c49f
--- /dev/null
+++ b/src/main/java/com/google/gwt/site/uploader/MarkdownFile.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2013 Daniel Kurka
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.site.uploader;
+
+import java.io.File;
+
+public class MarkdownFile {
+
+	private final String path;
+	private final File file;
+
+	public MarkdownFile(String path, File file) {
+		this.path = path;
+		this.file = file;
+
+	}
+
+	public String getPath() {
+		return path;
+	}
+
+	public File getFile() {
+		return file;
+	}
+}
diff --git a/src/main/java/com/google/gwt/site/uploader/Uploader.java b/src/main/java/com/google/gwt/site/uploader/Uploader.java
new file mode 100644
index 0000000..dfcd2c2
--- /dev/null
+++ b/src/main/java/com/google/gwt/site/uploader/Uploader.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2013 Daniel Kurka
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.site.uploader;
+
+import com.google.appengine.api.datastore.DatastoreService;
+import com.google.appengine.api.datastore.DatastoreServiceFactory;
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Text;
+import com.google.appengine.repackaged.com.google.api.client.util.Base64;
+import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
+import com.google.appengine.tools.remoteapi.RemoteApiOptions;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+
+public class Uploader {
+
+  public static void main(String[] args) {
+
+    if (args.length != 2) {
+      System.out.println("Usage Uploader <filesDir> <credentialsFile>");
+      throw new IllegalArgumentException("Usage Uploader <filesDir> <credentialsFile>");
+    }
+
+    String filesDir = args[0];
+    System.out.println("files directory: '" + filesDir + "'");
+
+    String credentialsFile = args[1];
+    System.out.println("credentials file: '" + credentialsFile + "'");
+
+    FileTraverser traverser = new FileTraverser(filesDir);
+    List<MarkdownFile> markdownFiles = traverser.traverse(args[0]);
+
+    Credentials credentials = readCredentialsFromFile(credentialsFile);
+
+    String username = credentials.getUsername();
+    String password = credentials.getPassword();
+    String host = credentials.getHost();
+    RemoteApiOptions options =
+        new RemoteApiOptions().server(host, 443).credentials(username, password);
+    RemoteApiInstaller installer = new RemoteApiInstaller();
+
+    try {
+      installer.install(options);
+      DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
+
+      for (MarkdownFile markdownFile : markdownFiles) {
+        uploadResource(ds, markdownFile);
+      }
+    } catch (IOException e) {
+      System.out.println("can not upload files");
+      throw new RuntimeException("can not upload files", e);
+    } finally {
+      installer.uninstall();
+    }
+  }
+
+  private static Credentials readCredentialsFromFile(String credentialsFile) {
+    FileInputStream inputStream = null;
+
+    try {
+      inputStream = new FileInputStream(new File(credentialsFile));
+      Properties properties = new Properties();
+      properties.load(inputStream);
+      String username = properties.getProperty("username");
+      if (username == null) {
+        System.out.println(
+            "No username found in credentials file, are you missing username=something");
+        throw new RuntimeException(
+            "No username found in credentials file, are you missing username=something");
+      }
+
+      String password = properties.getProperty("password");
+      if (password == null) {
+        System.out.println(
+            "No password found in credentials file, are you missing password=something");
+        throw new RuntimeException(
+            "No password found in credentials file, are you missing password=something");
+      }
+
+      String host = properties.getProperty("host");
+      if (host == null) {
+        System.out.println("No host found in credentials file, are you missing host=something");
+        throw new RuntimeException(
+            "No host found in credentials file, are you missing host=something");
+      }
+
+      return new Credentials(host, username, password);
+
+    } catch (IOException e) {
+      System.out.println("can not load credential files");
+      throw new RuntimeException("can not load credential files", e);
+    } finally {
+      IOUtils.closeQuietly(inputStream);
+    }
+
+  }
+
+  private static void uploadResource(DatastoreService ds, MarkdownFile markdownFile)
+      throws FileNotFoundException, IOException {
+
+    System.out.println("uploading file: '" + markdownFile.getPath() + "'");
+
+    Entity entity = new Entity("DocModel", markdownFile.getPath().substring(1));
+
+    String text = null;
+    FileInputStream fileInputStream = null;
+    try {
+      fileInputStream = new FileInputStream(markdownFile.getFile());
+      if (isBinaryFile(markdownFile.getPath())) {
+        byte[] byteArray = IOUtils.toByteArray(fileInputStream);
+        text = Base64.encodeBase64String(byteArray);
+      } else {
+        text = IOUtils.toString(fileInputStream, "UTF-8");
+      }
+
+      entity.setProperty("html", new Text(text));
+
+      ds.put(entity);
+    } finally {
+      IOUtils.closeQuietly(fileInputStream);
+    }
+  }
+
+  private static boolean isBinaryFile(String path) {
+    return path.endsWith(".png") || path.endsWith(".jpg") || path.endsWith(".gif");
+  }
+
+}