// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: TargetBlog.java,v 1.6 2008/03/31 14:48:14 spyromus Exp $
//
package com.salas.bb.remixfeeds.prefs;
import com.jgoodies.binding.beans.Model;
import com.salas.bb.remixfeeds.api.IWeblogAPI;
import com.salas.bb.remixfeeds.api.WeblogAPIs;
import com.salas.bb.remixfeeds.templates.Templates;
import com.salas.bb.utils.IdNameHolder;
import com.salas.bb.utils.i18n.Strings;
import javax.swing.*;
import java.text.MessageFormat;
import java.util.prefs.Preferences;
/**
* Single blog preferences.
*/
public class TargetBlog extends Model
{
private static final MessageFormat FMT = new MessageFormat("blog.{0}.{1}");
public static final String PROP_TITLE = "title";
public static final String PROP_API_URL = "apiURL";
public static final String PROP_API_TYPE = "apiType";
public static final String PROP_USER = "user";
public static final String PROP_PASSWORD = "password";
public static final String PROP_DEFAULT_CATEGORY = "defaultCategory";
public static final String PROP_DRAFT = "draft";
public static final String PROP_MODE = "mode";
public static final String PROP_BLOG = "blog";
public static final String PROP_TEMPLATE_NAME = "templateName";
public static final int MODE_TITLE_AND_LINK = 0;
public static final int MODE_EXCERPT_AND_LINK = 1;
public static final int MODE_FULL_TEXT = 2;
protected String title;
protected String apiURL;
protected IWeblogAPI apiType;
protected String user;
protected String password;
protected Category defaultCategory;
protected boolean draft;
protected int mode;
protected Blog blog;
// Simple storage (no need to persist)
private Category[] categories = new Category[0];
private Blog[] blogs = new Blog[0];
// The name of a template to use as default
protected String templateName;
/**
* Returns blog title.
*
* @return title.
*/
public String getTitle()
{
return title;
}
/**
* Sets blog title.
*
* @param title title.
*/
public void setTitle(String title)
{
String oldTitle = this.title;
this.title = title;
firePropertyChange(PROP_TITLE, oldTitle, title);
}
/**
* Returns XMLRPC API url.
*
* @return API URL.
*/
public String getApiURL()
{
return apiURL;
}
/**
* Sets XMLRPC API URL.
*
* @param apiURL API URL.
*/
public void setApiURL(String apiURL)
{
String oldApiURL = this.apiURL;
this.apiURL = apiURL;
firePropertyChange(PROP_API_URL, oldApiURL, apiURL);
}
/**
* Returns XMLRPC API type.
*
* @return API type.
*/
public IWeblogAPI getApiType()
{
return apiType;
}
/**
* Sets XMLRPC API type.
*
* @param apiType API type.
*/
public void setApiType(IWeblogAPI apiType)
{
IWeblogAPI oldApiType = this.apiType;
this.apiType = apiType;
firePropertyChange(PROP_API_TYPE, oldApiType, apiType);
}
/**
* Returns user name of the blog.
*
* @return user name.
*/
public String getUser()
{
return user;
}
/**
* Sets user name of the blog.
*
* @param user user name.
*/
public void setUser(String user)
{
String oldUser = this.user;
this.user = user;
firePropertyChange(PROP_USER, oldUser, user);
}
/**
* Returns user password to access XML API.
*
* @return user password.
*/
public String getPassword()
{
return password;
}
/**
* Sets user password to access XML API.
*
* @param password password.
*/
public void setPassword(String password)
{
String oldPassword = this.password;
this.password = password;
firePropertyChange(PROP_PASSWORD, oldPassword, password);
}
/**
* Returns default category to post to.
*
* @return default category.
*/
public Category getDefaultCategory()
{
return defaultCategory;
}
/**
* Sets default category to post to.
*
* @param defaultCategory default category.
*/
public void setDefaultCategory(Category defaultCategory)
{
Category oldDefaultCategory = this.defaultCategory;
this.defaultCategory = defaultCategory;
firePropertyChange(PROP_DEFAULT_CATEGORY, oldDefaultCategory, defaultCategory);
}
/**
* Returns <code>TRUE</code> if posts should be sent as drafts by default.
*
* @return <code>TRUE</code> if posts should be sent as drafts by default.
*/
public boolean isDraft()
{
return draft;
}
/**
* Sets the draft by default flag.
*
* @param draft <code>TRUE</code> if posts should be sent as drafts by default.
*/
public void setDraft(boolean draft)
{
boolean oldDraft = this.draft;
this.draft = draft;
firePropertyChange(PROP_DRAFT, oldDraft, draft);
}
/**
* Returns the mode.
*
* @return mode.
*/
public int getMode()
{
return mode;
}
/**
* Sets the new mode.
*
* @param mode mode.
*/
public void setMode(int mode)
{
int oldMode = this.mode;
this.mode = mode;
firePropertyChange(PROP_MODE, oldMode, mode);
}
/**
* Returns currently selected blog.
*
* @return blog.
*/
public Blog getBlog()
{
return blog;
}
/**
* Sets new selected blog.
*
* @param blog blog.
*/
public void setBlog(Blog blog)
{
Blog old = this.blog;
this.blog = blog;
firePropertyChange(PROP_BLOG, old, blog);
}
/**
* Returns the template name.
*
* @return template name.
*/
public String getTemplateName()
{
String name = templateName;
if (name == null) name = Templates.fromOldMode(mode);
return name;
}
/**
* Sets the name of the template to use for rendering.
*
* @param name template name.
*/
public void setTemplateName(String name)
{
String oldTemplateName = templateName;
templateName = name;
firePropertyChange(PROP_TEMPLATE_NAME, oldTemplateName, templateName);
}
/**
* Creates and returns a copy of this object.
*
* @return a clone of this instance.
*/
protected TargetBlog createClone()
{
TargetBlog prefs = new TargetBlog();
prefs.setTitle(getTitle());
prefs.setApiURL(getApiURL());
prefs.setApiType(getApiType());
prefs.setUser(getUser());
prefs.setPassword(getPassword());
prefs.setDraft(isDraft());
prefs.setMode(getMode());
prefs.setDefaultCategory(getDefaultCategory());
prefs.setCategories(getCategories());
prefs.setBlog(getBlog());
prefs.setBlogs(getBlogs());
prefs.setTemplateName(getTemplateName());
return prefs;
}
// ----------------------------------------------------------------------------------
// Storage attributes
// ----------------------------------------------------------------------------------
/**
* Returns the list of categories.
*
* @return categories.
*/
public Category[] getCategories()
{
return categories;
}
/**
* Updates categories with new list.
*
* @param newList new list to be copied to the categories lookup.
*/
public void setCategories(Category[] newList)
{
categories = newList == null ? new Category[0] : newList;
}
/**
* Returns the list of blogs.
*
* @return blogs.
*/
public Blog[] getBlogs()
{
return blogs;
}
/**
* Sets the map of blogs.
*
* @param newList new map.
*/
public void setBlogs(Blog[] newList)
{
blogs = newList == null ? new Blog[0] : newList;
}
// ----------------------------------------------------------------------------------
// Work methods
// ----------------------------------------------------------------------------------
/**
* Tests the connection to the blog using this configuration.
*
* @return <code>NULL</code> if fine or error message.
*/
public String testConnection()
{
return apiType == null
? Strings.message("ptb.prefs.details.setup.status.noapi")
: apiType.validateBlog(this);
}
// ----------------------------------------------------------------------------------
// Persistence
// ----------------------------------------------------------------------------------
/**
* Stores its preferences as a blog number <code>cnt</code>.
*
* @param cnt sequence number of this blog.
* @param prefs preferences map.
*/
void store(int cnt, Preferences prefs)
{
String n = Integer.toString(cnt);
put(prefs, n, PROP_TITLE, getTitle());
put(prefs, n, PROP_API_URL, getApiURL());
put(prefs, n, PROP_API_TYPE, getApiType().getTypeID());
put(prefs, n, PROP_USER, getUser());
put(prefs, n, PROP_PASSWORD, getPassword());
Category.store(prefs, prop(n, PROP_DEFAULT_CATEGORY), getDefaultCategory());
Blog.store(prefs, prop(n, PROP_BLOG), getBlog());
put(prefs, n, PROP_DRAFT, isDraft());
put(prefs, n, PROP_MODE, Integer.toString(getMode()));
put(prefs, n, PROP_TEMPLATE_NAME, getTemplateName());
}
/**
* Fetches preferences from the record for a blog number <code>cnt</code>.
*
* @param cnt sequence number of a blog.
* @param prefs preferences map.
*/
void restore(int cnt, Preferences prefs)
{
String n = Integer.toString(cnt);
setTitle(get(prefs, n, PROP_TITLE));
setApiURL(get(prefs, n, PROP_API_URL));
setApiType(getApiType(prefs, n, PROP_API_TYPE));
setUser(get(prefs, n, PROP_USER));
setPassword(get(prefs, n, PROP_PASSWORD));
setDefaultCategory(Category.restore(prefs, prop(n, PROP_DEFAULT_CATEGORY)));
setBlog(Blog.restore(prefs, prop(n, PROP_BLOG)));
setDraft(getBoolean(prefs, n, PROP_DRAFT));
setMode(getInteger(prefs, n, PROP_MODE, MODE_FULL_TEXT));
setTemplateName(get(prefs, n, PROP_TEMPLATE_NAME));
}
/**
* Returns integer value from the preferences map.
*
* @param prefs preferences map.
* @param cnt sequence number of a blog.
* @param name property name.
* @param def default value.
*
* @return value.
*/
private int getInteger(Preferences prefs, String cnt, String name, int def)
{
return prefs.getInt(prop(cnt, name), def);
}
/**
* Returns boolean value from the preferences map.
*
* @param prefs preferences map.
* @param cnt sequence number of a blog.
* @param name property name.
*
* @return property value.
*/
private boolean getBoolean(Preferences prefs, String cnt, String name)
{
return prefs.getBoolean(prop(cnt, name), false);
}
/**
* Returns API type from the preferences map.
*
* @param prefs preferences map.
* @param cnt sequence number of a blog.
* @param name property name.
*
* @return property value.
*/
private IWeblogAPI getApiType(Preferences prefs, String cnt, String name)
{
String apiTypeID = get(prefs, cnt, name);
return WeblogAPIs.getWeblogAPIByID(apiTypeID);
}
/**
* Gets a string value of a property.
*
* @param prefs preferences map.
* @param cnt sequence number of a blog.
* @param name property name.
*
* @return property value.
*/
private String get(Preferences prefs, String cnt, String name)
{
return prefs.get(prop(cnt, name), null);
}
/**
* Puts the string representation of an object to the preferences map if
* the object is not <code>NULL</code>.
*
* @param prefs preferences map.
* @param cnt sequence number of a blog.
* @param name property name.
* @param value property value.
*/
private static void put(Preferences prefs, String cnt, String name, Object value)
{
if (value == null) return;
prefs.put(prop(cnt, name), value.toString());
}
/**
* Returns the property name for the property.
*
* @param cnt blog sequence number.
* @param prop property name.
*
* @return name.
*/
private static String prop(String cnt, String prop)
{
return FMT.format(new Object[] { cnt, prop });
}
/**
* Returns a string representation of the object.
*
* @return a string representation of the object.
*/
public String toString()
{
return title;
}
/**
* Loads categories asynchronously and calls the callback from within
* the EDT when finished.
*
* @param edtCallback callback.
*/
public void loadCategories(final Runnable edtCallback)
{
new Thread("Loading Categories")
{
{ setDaemon(true); }
/** Invoked when loading starts. */
public void run()
{
try
{
Category[] loadedCategories = getApiType().getCategories(TargetBlog.this);
if (loadedCategories != null && loadedCategories.length == 0)
{
loadedCategories = new Category[] { getApiType().getDefaultCategory() };
}
setCategories(loadedCategories);
} finally
{
SwingUtilities.invokeLater(edtCallback);
}
}
}.start();
}
public void loadBlogs(final Runnable edtCallback)
{
new Thread("Loading Blogs")
{
{ setDaemon(true); }
/** Invoked when loading starts. */
public void run()
{
try
{
setBlogs(getApiType().getBlogs(TargetBlog.this));
} finally
{
SwingUtilities.invokeLater(edtCallback);
}
}
}.start();
}
/**
* Simple holder for blog information.
*/
public static class Blog extends IdNameHolder
{
/**
* Creates holder.
*
* @param id id.
* @param name name.
*/
public Blog(String id, String name)
{
super(id, name);
}
/**
* Restores blog.
*
* @param prefs preferences.
* @param prop propery name.
*
* @return blog or <code>NULL</code>.
*/
public static Blog restore(Preferences prefs, String prop)
{
IdNameHolder hld = restore0(prefs, prop);
return hld == null ? null : new Blog(hld.id, hld.name);
}
}
/**
* Simple holder for category information.
*/
public static class Category extends IdNameHolder
{
/**
* Creates holder.
*
* @param id id.
* @param name name.
*/
public Category(String id, String name)
{
super(id, name);
}
/**
* Restores category.
*
* @param prefs preferences.
* @param prop propery name.
*
* @return category or <code>NULL</code>.
*/
public static Category restore(Preferences prefs, String prop)
{
IdNameHolder hld = restore0(prefs, prop);
return hld == null ? null : new Category(hld.id, hld.name);
}
}
}