/src/com/atlassian/uwc/converters/smf/AttachmentConverter.java
Java | 245 lines | 206 code | 23 blank | 16 comment | 48 complexity | 1e28a1a94ea92ecb4fa1fe5348104386 MD5 | raw file
- package com.atlassian.uwc.converters.smf;
- import java.io.File;
- import java.io.FileFilter;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.nio.channels.FileChannel;
- import java.util.Properties;
- import java.util.Vector;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.apache.log4j.Logger;
- import com.atlassian.uwc.converters.BaseConverter;
- import com.atlassian.uwc.exporters.SMFExporter;
- import com.atlassian.uwc.hierarchies.MetaHierarchy;
- import com.atlassian.uwc.ui.Page;
- public class AttachmentConverter extends BaseConverter {
- private static final String PROPKEY_REMOVE = "attachment-chars-remove";
- private static final String PROPKEY_TOUNDERSCORE = "attachment-chars-to-underscore";
- Logger log = Logger.getLogger(this.getClass());
- public void convert(Page page) {
- Properties meta = null;
- try {
- meta = MetaHierarchy.getMeta(page);
- } catch (IOException e) {
- log.error("Problem getting meta data for file: " + page.getFile().getAbsolutePath());
- e.printStackTrace();
- return;
- }
- String delim = meta.getProperty("attachments.delim", SMFExporter.Data.ATTACH_DELIM);
- Vector<String> filepaths = getAttachmentPaths(meta.getProperty("attachments.location", ""), delim);
- Vector<String> tmppaths = createTmpPaths(meta.getProperty("attachments.name", ""), page.getFile().getParent(), delim);
- copyToTmp(filepaths, tmppaths);
- attach(page, tmppaths);
- }
-
- protected Vector<String> getAttachmentPaths(String attachments) {
- return getAttachmentPaths(attachments, SMFExporter.Data.ATTACH_DELIM);
- }
- protected Vector<String> getAttachmentPaths(String attachments, String delim) {
- String out = this.getAttachmentDirectory();
- return createPaths(attachments, out, delim);
- }
- private Vector<String> createPaths(String files, String parent, String delim) {
-
- Vector<String> paths = new Vector<String>();
- if (files == null || "".equals(files) || "null".equals(files)) return paths;
- String[] all = splitFiles(files, delim);
- if (!parent.endsWith(File.separator)) parent += File.separator;
- for (int i = 0; i < all.length; i++) {
- String att = all[i];
- att = att.trim();
- att = removeChars(att);
- att = toUnderscore(att);
- paths.add(parent + att);
- }
- return paths;
- }
- private String[] splitFiles(String files, String delim) {
- String[] all;
- if (delim == null) all = new String[] {files};
- else all = files.split(delim);
- return all;
- }
- private String toUnderscore(String att) {
- String toUnderscoreChars = getToUnderscoreChars();
- if (toUnderscoreChars != null && !"".equals(toUnderscoreChars)) {
- for (int j = 0; j < toUnderscoreChars.length(); j++) {
- String c = Character.toString(toUnderscoreChars.charAt(j));
- //can't use a char class. how do we know what to escape?
- att = att.replaceAll("\\Q"+c+"\\E", "_");
- }
- }
- return att;
- }
- private String removeChars(String att) {
- String removeChars = getRemoveChars();
- if (removeChars != null && !"".equals(removeChars)) {
- for (int j = 0; j < removeChars.length(); j++) {
- String c = Character.toString(removeChars.charAt(j));
- //can't use a char class. how do we know what to escape?
- att = att.replaceAll("\\Q"+c+"\\E", "");
- }
- }
- return att;
- }
- private String getRemoveChars() {
- Properties props = this.getProperties();
- if (props.containsKey(PROPKEY_REMOVE))
- return props.getProperty(PROPKEY_REMOVE, null);
- return null;
- }
- private String getToUnderscoreChars() {
- Properties props = this.getProperties();
- if (props.containsKey(PROPKEY_TOUNDERSCORE))
- return props.getProperty(PROPKEY_TOUNDERSCORE, null);
- return null;
- }
- protected Vector<String> createTmpPaths(String attachments, String gparent) {
- return createTmpPaths(attachments, gparent, SMFExporter.Data.ATTACH_DELIM);
- }
- protected Vector<String> createTmpPaths(String attachments, String gparent, String delim) {
- if (!gparent.endsWith(File.separator)) gparent += File.separator;
- String parent = gparent + "attachments";
- File parentFile = new File(parent);
- if (!parentFile.exists()) parentFile.mkdir();
- return createPaths(attachments, parent, delim);
- }
-
- protected void copyToTmp(Vector<String> filepaths, Vector<String> tmppaths) {
- if (filepaths == null || tmppaths == null) {
- String error = "Attachments vectors are null. Cannot copy attachments to tmp.";
- log.error(error);
- addError(Feedback.CONVERTER_ERROR, error, true);
- return;
- }
- if (filepaths.size() != tmppaths.size()) {
- String error = "Attachments vectors must be the same size. Cannot copy attachments to tmp.";
- log.error(error);
- addError(Feedback.CONVERTER_ERROR, error, true);
- return;
- }
- for (int i = 0; i < filepaths.size(); i++) {
- String from = filepaths.get(i);
- String to = tmppaths.get(i);
- if (from == null || to == null) {
- log.error("Problem copying attachment file: '" + from + "' to '" + to + "'. Skipping.");
- continue;
- }
- try {
- copyFile(new File(from), new File(to));
- } catch (IOException e) {
- log.warn("Problem copying attachment file: '" + from + "' to '" + to + "'." +
- " Attempting to find alternate attachment file.");
- //try to find the right attachment using the unique file id from the attachments dir
- try {
- from = getAlternateFilepath(from);
- copyFile(new File(from), new File(to));
- log.info("Correctly copied alternate attachment file: " + from);
- continue;
- } catch (IOException e1) {
- log.error("Could not find attachment file. Skipping.");
- e1.printStackTrace();
- }
- e.printStackTrace();
- continue;
- }
- }
- }
-
- /**
- * copies file to newFile
- * Note: copied from Jspwiki converter's ImageConverter
- * @param file
- * @param newFile
- * @throws FileNotFoundException
- * @throws IOException
- */
- protected void copyFile(File file, File newFile) throws FileNotFoundException, IOException {
- log.debug("Copying '" + file.getAbsolutePath() + "' to '" + newFile.getAbsolutePath() + "'");
- if (!file.exists()) log.debug("File doesn't exist. Cannot copy: " + file.getAbsolutePath());
- // Create channel on the source
- FileChannel srcChannel = new FileInputStream(file.getAbsolutePath()).getChannel();
-
- // Create channel on the destination
- FileChannel dstChannel = new FileOutputStream(newFile.getAbsolutePath()).getChannel();
-
- // Copy file contents from source to destination
- int buffersize = -1;
- try {
- //see if the user specified a buffer size
- String buffersizeStr = getProperties().getProperty("buffer-size", null);
- if (buffersizeStr != null) {
- try {
- buffersize = Integer.parseInt(buffersizeStr);
- }
- catch (NumberFormatException en) {
- log.error("Property buffer-size is not an integer. Using filesize.");
- }
- }
- if (buffersize > 0) { //user set buffersize - see Michael Grove's code in UWC-349
- long size = srcChannel.size();
- long position = 0;
- while (position < size) {
- position += srcChannel.transferTo(position, buffersize, dstChannel);
- }
- }
- else { //if no user specified buffer size, use filesize
- dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
- }
- } catch (FileNotFoundException e) {
- throw e;
- } catch (IOException e2) {
- throw e2;
- } catch (RuntimeException e3) {
- throw e3;
- } finally {
- // Close the channels
- srcChannel.close();
- dstChannel.close();
- if (!newFile.exists()) log.error("Copying file unsuccessful. New file does not exist: " + newFile.getAbsolutePath());
- }
- }
- Pattern fileid = Pattern.compile("\\/(\\d+)[^\\/]+$");
- private String getAlternateFilepath(String path) throws IOException {
- Matcher idFinder = fileid.matcher(path);
- final String fileid = (idFinder.find())?idFinder.group(1):null;
- if (fileid == null) throw new IOException("Couldn't find fileId in: " + path);
- File dir = new File(this.getAttachmentDirectory());
- File[] files = dir.listFiles(new FileFilter() {
- public boolean accept(File candidate) {
- return candidate.getName().startsWith(fileid + "_");
- }
- });
- if (files == null || files.length < 1) throw new IOException("Couldn't find fileId in: " + path);
- if (files.length > 1) log.warn("Found multiple files with unique id! Using first one.");
- return files[0].getAbsolutePath();
- }
-
- protected void attach(Page page, Vector<String> filepaths) {
- for (String path : filepaths) {
- File file = new File(path);
- if (!file.exists()) log.warn("Could not find attachment at location: " + path);
- if (!file.isFile()) log.warn("Attachment is not a file: " + path);
- page.addAttachment(file);
- }
- }
- }