blob: 0fbc71fd308924fbe92424c9749959a7bc360fca [file] [log] [blame]
package com.atlassian.uwc.ui;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.List;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import com.atlassian.uwc.converters.tikiwiki.RegexUtil;
import com.atlassian.uwc.ui.UWCUserSettings.Setting;
import com.atlassian.uwc.ui.listeners.FeedbackHandler.Feedback;
import com.atlassian.uwc.util.PropertyFileManager;
/**
* This object contains the underlying data for the UWC. It's essentially a gateway to allow
* different classes to communicate with each other. For example, it:
* - provides access to the file system for
* -- getting saved and saving user settings
* -- converter properties files
* -- info about existance of properties files
* - maintains user chosen wiki pages information
* - provides access to the converter engine, for converting, and also getting error codes and feedback
* from the ConverterEngine
* Note: heavily influenced by UWCForm2 and ChooseWikiForm code from the
* UWC GUI v.2
*/
public class UWCGuiModel {
Logger log = Logger.getLogger(this.getClass());
/**
* list of wiki converters, gathered from converter.xxx.properties files
*/
private Vector<String> converterListModel = null;
/**
* list of wiki exporters, gathered from exporter.xxx.properties files
*/
private Vector<String> exportListModel = null;
/**
* list of user chosen pages
*/
private Vector<String> pageNames = null;
/**
* engine that runs the conversions
*/
private ConverterEngine engine = null;
/**
* user settings
*/
private UWCUserSettings userSettings = null;
/**
* which setting the user is currently changing, and has not been saved yet
*/
private UWCUserSettings.Setting unsaved = null;
public UWCGuiModel() {
userSettings = new UWCUserSettings();
loadSavedPages(userSettings);
}
public UWCGuiModel(UWCUserSettings settings) {
this.userSettings = settings;
loadSavedPages(userSettings);
}
/**
* gets the list of available wiki types that can be converted
* @param parentDir directory in which the wiki properties files can be found
* Example: "conf"
* @return list of wiki types
*/
public Vector<String> getWikiTypesList(String parentDir) {
FilenameFilter filter = new UWCConverterPropFileFilter();
return getFromFileList(parentDir, filter, this.converterListModel);
}
/**
* gets the list of available exportable wiki types
* @param parentDir directory in which export properties files can be found
* Example: "conf"
* @return list of export wiki types
*/
public Vector<String> getExportTypes(String parentDir) {
FilenameFilter filter = new UWCConverterExportFileFilter();
return getFromFileList(parentDir, filter, this.exportListModel);
}
/**
* creates or gets a list of wiki types that
* exist in the given parentDir,
* conform to the given filter,
* and are maintained in the given model
* @param parentDir directory in which the files representing the desired data exist
* @param filter file filter which restricts which files contain the desired data
* @param model object that maintains the desired data. If it is not null, the return value
* will be this object
* @return model or newly created list of wiki types
*/
public Vector<String> getFromFileList(String parentDir, FilenameFilter filter, Vector<String> model) {
//return existing object, if it exists
if (model != null)
return model;
File confDir = new File(parentDir);
//check for errors
if (!confDir.exists()) {
log.error("confDir " + confDir.getAbsolutePath() + " does not exist");
return new Vector<String>(); //return empty list
}
if (!confDir.isDirectory()) {
log.error("confDir " + confDir.getAbsolutePath() + " is not a directory!");
return new Vector<String>();
}
//create the list
File[] files = confDir.listFiles(filter);
model = new Vector<String>();
for (File file : files) {
String fileName = file.getName();
StringTokenizer st = new StringTokenizer(fileName, ".");
st.nextToken();
fileName = st.nextToken();
model.add(fileName);
}
return model;
}
/**
* @param files adds the given files to the pages state
* @return current list of pages after additions
*/
public Vector<String> addWikiPages(File[] files) {
pageNames = getPageNames();
for (File file : files) {
pageNames.add(file.getPath());
}
return this.pageNames;
}
/**
* @return the directory that the user chose pages from most recently
*/
public String getPageChooserDir() {
return this.userSettings.getPageChooserDir();
}
/**
* removes the given pages from the internal list of files
* @param files
* @return resulting list of pagenames after removals
*/
public Vector<String> removeWikiPages(Object[] files) {
for (Object file : files) {
String item = (String) file;
pageNames.remove(item);
}
return pageNames;
}
/**
* run the conversion
* @param propsPath path to the converter properties file that will
* be used to run the conversion
* @throws IOException, {@link IllegalArgumentException} if there are problems reading the given converter
* properties files
*/
public void convert(String propsPath) throws IOException, IllegalArgumentException {
ConverterEngine engine = getConverterEngine();
List<File> pages = getPageFiles();
List<String> converters = getConverters(propsPath);
engine.convert(pages, converters, this.userSettings);
}
/**
* cancels the currently being run conversion
*/
public void cancelConvert() {
ConverterEngine engine = getConverterEngine();
engine.cancel();
}
/**
* gets a list of converter strings from the file at the given propsPath
* @param propsPath converter.xxx.properties file representing this wiki
* @return list of converter strings
* @throws IOException if can't load the properties from the given file at propsPath
*/
protected List<String> getConverters(String propsPath) throws IOException {
File props = new File(propsPath);
if (!props.exists()) {
String message = "No property file at that location: " + propsPath;
log.error(message);
throw new IllegalArgumentException(message);
}
TreeMap<String,String> converters = null;
converters = PropertyFileManager.loadPropertiesFile(propsPath);
if (converters == null)
throw new IllegalArgumentException(); //unlikely, as the error handling above should be sufficient
return getConvertersAsStrings(converters);
}
/**
* gets a list of syntax converters from the given converters map
* @param converters
* @return list of syntax converters
*/
protected List<String> getConvertersAsStrings(TreeMap<String, String> converters) {
Vector<String> converterStrings = new Vector<String>(converters.keySet().size());
for (String converter : converters.keySet()) {
String value = converters.get(converter);
String converterString = converter + "=" + value;
converterStrings.add(converterString);
}
return converterStrings;
}
/**
* @return creates a list of File objects from the saved pagenames state
*/
protected List<File> getPageFiles() {
Vector<File> files = new Vector<File>();
this.pageNames = getPageNames();
for (String path : this.pageNames) {
File file = new File(path);
files.add(file);
}
return files;
}
/**
* @return gets the converter engine used to run conversions
*/
private ConverterEngine getConverterEngine() {
if (this.engine == null) {
this.engine = new ConverterEngine();
}
return this.engine;
}
/**
* @return the page names representing the pages the user has chosen to convert
*/
public Vector<String> getPageNames() {
if (this.pageNames == null)
this.pageNames = new Vector<String>();
return this.pageNames;
}
Pattern paths = Pattern.compile("" +
"(.*?)" + //everything until
"(?>::|$)"); //double colon or end of string
/**
* loads the saved pages setting data into the model's pagenames object
* @param settings
*/
private void loadSavedPages(UWCUserSettings settings) {
String pagestring = settings.getSetting(Setting.PAGES);
Matcher pathFinder = paths.matcher(pagestring);
Vector<String> pagenames = getPageNames();
while (pathFinder.find()) {
String path = pathFinder.group(1);
if ("".equals(path)) continue;
pagenames.add(path);
}
}
/**
* file filter that accepts converter properties files
*/
public class UWCConverterPropFileFilter implements FilenameFilter {
private static final String PROPFILE_PREFIX = "converter";
private static final String PROPFILE_SUFFIX = ".properties";
public boolean accept(File dir, String name) {
if (name.equalsIgnoreCase(PROPFILE_PREFIX + PROPFILE_SUFFIX)) return false;
if (name.startsWith(PROPFILE_PREFIX) &&
name.endsWith(PROPFILE_SUFFIX)) {
return true;
}
return false;
}
}
/**
* file filter that accepts exporter properties files
*/
public class UWCConverterExportFileFilter implements FilenameFilter {
private static final String FILE_PREFIX = "exporter";
private static final String FILE_SUFFIX = ".properties";
public boolean accept(File dir, String name) {
if (name.equalsIgnoreCase(FILE_PREFIX + FILE_SUFFIX)) return false;
if (name.startsWith(FILE_PREFIX) &&
name.endsWith(FILE_SUFFIX)) {
return true;
}
return false;
}
}
/**
* @return directory where the converted files will be saved before upload
*/
public static String getOutputDir() {
return "output" + File.separator + "output";
}
/**
* sets the given setting with the given value. And
* saves all the current settings to the settings file
* @param setting
* @param value
* @return feedback on the process of saving the file
*/
public Feedback saveSetting(Setting setting, String value) {
this.userSettings.setOneSetting(setting, value);
this.userSettings.saveSettingsToFile();
return this.userSettings.feedback;
}
/**
* saves all settings to the file system
*/
public void saveAllSettings() {
log.debug("Saving All Settings");
this.userSettings.saveSettingsToFile();
}
/**
* @param setting
* @return gets the value for the given setting
*/
public String getSetting(Setting setting) {
return this.userSettings.getSetting(setting);
}
/**
* registers the given feedback window by:
* * getting the state from the engine
* * assigning that state to the feedback window
* @param feedbackWindow
*/
public void registerFeedbackWindow(FeedbackWindow feedbackWindow) {
ConverterEngine engine = getConverterEngine();
State state = engine.getState(this.userSettings);
feedbackWindow.setState(state);
}
/**
* @return gets the feedback from the converter engine
*/
public Feedback getConverterFeedback() {
ConverterEngine engine = getConverterEngine();
return engine.getConverterFeedback();
}
/**
* @return gets and clears error messages
*/
public ConverterErrors getErrors() {
ConverterEngine engine = getConverterEngine();
return engine.getErrors();
}
/**
* @return true if the conversion generated errors
*/
public boolean getHadConverterErrors() {
ConverterEngine engine = getConverterEngine();
return engine.hadConverterErrors();
}
/**
* @return the setting that is currently being updated by the user
*/
public Setting getUnsaved() {
return this.unsaved;
}
/**
* setter
* @param setting
*/
public void setUnsaved(Setting setting) {
this.unsaved = setting;
}
}