/*******************************************************************************
* Copyright 2012 Pearson Education
*
* 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 org.semantictools.web.upload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.semantictools.context.renderer.model.ContextProperties;
import org.semantictools.frame.api.LinkManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A client that uploads files associated with a media type to
* semantic-tools.appspot.com
*
* @author Greg McFall
*
*/
public class AppspotUploadClient {
private static final Logger logger = LoggerFactory.getLogger(AppspotUploadClient.class);
private static final String SERVLET_URL = "http://semantic-tools.appspot.com/admin/upload.do";
// private static final String SERVLET_URL = "http://127.0.0.1:8888/admin/upload.do";
private static final String CONTENT_TYPE = "contentType";
private static final String PATH = "path";
private static final String VERSION = "version";
private static final String FILE_UPLOAD = "fileUpload";
private static final String CHECKSUM_PROPERTIES = "checksum.properties";
private String servletURL = SERVLET_URL;
private String version;
private Properties checksumProperties;
public void uploadAll(File baseDir) throws IOException {
LinkManager linkManager = new LinkManager(baseDir);
loadCheckSumProperties(baseDir);
uploadFiles(linkManager, baseDir);
saveCheckSumProperties(baseDir);
}
private void saveCheckSumProperties(File baseDir) throws IOException {
File file = new File(baseDir, CHECKSUM_PROPERTIES);
FileOutputStream out = new FileOutputStream(file);
checksumProperties.store(out, null);
checksumProperties = null;
}
private void loadCheckSumProperties(File baseDir) throws IOException {
checksumProperties = new Properties();
File file = new File(baseDir, CHECKSUM_PROPERTIES);
if (file.exists()) {
FileReader reader = new FileReader(file);
try {
checksumProperties.load(reader);
} finally {
reader.close();
}
}
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getEndpointURL() {
return servletURL;
}
public void setEndpointURL(String endpointURL) {
this.servletURL = endpointURL;
}
private void uploadFiles(LinkManager linkManager, File dir) throws IOException {
File[] array = dir.listFiles();
for (File file : array) {
if (file.isDirectory()) {
uploadFiles(linkManager, file);
} else {
String fileName = file.getName();
int dot = fileName.lastIndexOf('.');
if (dot < 0) continue;
String suffix = fileName.substring(dot+1);
String contentType = getContentType(suffix);
if (contentType == null) continue;
String path = linkManager.relativize(file);
upload(contentType, path, file);
}
}
}
private String getContentType(String suffix) {
return
"png".equals(suffix) ? "image/png" :
"html".equals(suffix) ? "text/html" :
"css".equals(suffix) ? "text/css" :
"json".equals(suffix) ? "application/json" :
null;
}
public void upload(File baseDir, ContextProperties contextProperties) throws IOException {
// String domain = contextProperties.getPurlDomain();
// if (domain == null) return;
// if (!domain.endsWith("/")) {
// domain = domain + "/";
// }
// if (!domain.startsWith("/")) {
// domain = "/" + domain;
// }
String mediaType = contextProperties.getMediaType();
// String path = domain + "mediatype/" + mediaType.replace('.', '/') + "/";
String path = "mediatype/" + mediaType.replace('.', '/') + "/";
upload(path, baseDir, contextProperties);
}
private void upload(String path, File dir, ContextProperties contextProperties) throws IOException {
File[] fileList = dir.listFiles();
if (fileList == null) return;
for (int i=0; i<fileList.length; i++) {
File file = fileList[i];
String fileName = file.getName();
if (file.isDirectory()) {
upload(path + fileName + "/" , file, contextProperties);
continue;
}
int dot = fileName.lastIndexOf('.');
String uri = path + fileName;
if (dot < 0) {
logger.debug("Skipping file because it has no suffix: " + uri);
continue;
}
String suffix = fileName.substring(dot+1);
String mediaType = MimeTypes.getMediaType(suffix);
if (mediaType == null) {
logger.debug("Skipping file because the media type is not known: " + uri);
continue;
}
upload(mediaType, uri, file);
}
}
public void upload(String contentType, String path, File file) throws IOException {
if (file.getName().equals(CHECKSUM_PROPERTIES)) {
return;
}
if (!path.startsWith("/")) {
path = "/" + path;
}
// Do not upload if we can confirm that we previously uploaded
// the same content.
String checksumKey = path.concat(".sha1");
String checksumValue = null;
try {
checksumValue = Checksum.sha1(file);
String prior = checksumProperties.getProperty(checksumKey);
if (checksumValue.equals(prior)) {
return;
}
} catch (NoSuchAlgorithmException e) {
// Ignore.
}
logger.debug("uploading... " + path);
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(servletURL);
post.setHeader("CONTENT-TYPE", "multipart/form-data; boundary=xxxBOUNDARYxxx");
MultipartEntity entity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE, "xxxBOUNDARYxxx", Charset.forName("UTF-8"));
FileBody body = new FileBody(file, contentType);
entity.addPart(CONTENT_TYPE, new StringBody(contentType));
entity.addPart(PATH, new StringBody(path));
if (version != null) {
entity.addPart(VERSION, new StringBody(version));
}
entity.addPart(FILE_UPLOAD, body);
post.setEntity(entity);
String response = EntityUtils.toString(client.execute(post).getEntity(), "UTF-8");
client.getConnectionManager().shutdown();
if (checksumValue != null) {
checksumProperties.put(checksumKey, checksumValue);
}
}
}