Skip to content

Commit

Permalink
refactored
Browse files Browse the repository at this point in the history
  • Loading branch information
kohsuke committed Oct 19, 2010
1 parent 4c23ab1 commit 9440e95
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 78 deletions.
Expand Up @@ -37,7 +37,7 @@
* @author Kohsuke Kawaguchi
*/
public abstract class SimplePersona extends Persona {
private final List<String> quotes;
private volatile List<String> quotes;
private final Random random = new Random();

/**
Expand All @@ -51,6 +51,10 @@ protected SimplePersona(String id, List<String> quotes) {
this.quotes = quotes;
}

protected void setQuotes(List<String> quotes) {
this.quotes = quotes;
}

/**
* Determines the icon and the background to render.
*/
Expand Down
111 changes: 111 additions & 0 deletions src/main/java/hudson/plugins/persona/xml/XmlBasedPersona.java
@@ -0,0 +1,111 @@
package hudson.plugins.persona.xml;

import hudson.model.AbstractBuild;
import hudson.model.Result;
import hudson.plugins.persona.simple.Image;
import hudson.plugins.persona.simple.SimplePersona;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
* {@link SimplePersona} implementation based on XML file.
*
* @author Kohsuke Kawaguchi
*/
public class XmlBasedPersona extends SimplePersona {
public final URL xml;
private final URL imageBase;
private final String imageBasePath;

private String icon;
private String success;
private String failure;
private String other;
private String displayName;

/**
* Parses a persona from an XML file.
*
* @param xml
* Location of the XML file.
* @param imageBase
* Base URL to find images like icon.png, success.jpg, and so on.
*/
public static XmlBasedPersona create(URL xml, URL imageBase, String imageBasePath) throws DocumentException, IOException {
Element r = new SAXReader().read(xml).getRootElement();
return new XmlBasedPersona(r,xml,imageBase,imageBasePath);
}

private XmlBasedPersona(Element r, URL xml, URL imageBase, String imageBasePath) throws IOException, DocumentException {
super(r.attributeValue("id"),new ArrayList<String>());

this.xml = xml;
this.imageBase = imageBase;
this.imageBasePath = imageBasePath;

reload();
}

/**
* Finds an image in ${imageBase}/${baseName}.* for some known extension
*/
private String findImage(URL imageBase, String imageBasePath, String baseName) throws IOException {
for (String ext : EXTENSIONS) {
try {
new URL(imageBase,baseName+ext).openStream().close();
// found it.
return imageBasePath+'/'+baseName+ext;
} catch (IOException e) {
// not found. try next
}
}
throw new IOException("No image found that matches "+imageBase+"/"+baseName+".*");
}

/**
* Reloads the configuration of this persona from its original XML.
*/
public void reload() throws IOException, DocumentException {
this.icon = findImage(imageBase, imageBasePath, "icon");
this.success = findImage(imageBase, imageBasePath, "success");
this.failure = findImage(imageBase, imageBasePath, "failure");
this.other = findImage(imageBase, imageBasePath, "other");

Element r = new SAXReader().read(xml).getRootElement();
this.displayName = r.attributeValue("displayName");

List<String> quotes = new ArrayList<String>();
for (Element e : (List<Element>)r.elements("quote")) {
quotes.add(e.getTextTrim());
}
setQuotes(quotes);
}

@Override
public Image getImage(AbstractBuild<?,?> build) {
Result r = build.getResult();
if (r== Result.SUCCESS)
return new Image(icon, success);
if (r== Result.FAILURE)
return new Image(icon, failure);
return new Image(icon, other);
}

@Override
public Image getDefaultImage() {
return new Image(icon, success);
}

public String getDisplayName() {
return displayName;
}

private static final String[] EXTENSIONS = {".jpg",".jpeg",".png",".gif",
".JPG",".JPEG",".PNG",".GIF"};
}
Expand Up @@ -21,21 +21,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.persona.simple;
package hudson.plugins.persona.xml;

import hudson.Extension;
import hudson.ExtensionComponent;
import hudson.ExtensionFinder;
import hudson.FilePath;
import hudson.PluginWrapper;
import hudson.model.AbstractBuild;
import hudson.model.Hudson;
import hudson.model.Result;
import hudson.plugins.persona.Persona;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.net.URL;
Expand All @@ -47,21 +42,17 @@
import java.util.logging.Logger;

/**
* Instantiates simple persona by looking at a known location in plugins.
* Instantiates {@link XmlBasedPersona}s }by looking at a known location in plugins.
*
* @author Kohsuke Kawaguchi
*/
@Extension
public class SimplePersonaFinder extends ExtensionFinder {
private static final String[] EXTENSIONS = {".jpg",".jpeg",".png",".gif",
".JPG",".JPEG",".PNG",".GIF"};


public class XmlPersonaFinder extends ExtensionFinder {
@Override
public <T> Collection<ExtensionComponent<T>> find(Class<T> type, Hudson hudson) {
if (type!=Persona.class) return Collections.emptyList();

List<ExtensionComponent<SimplePersona>> r = new ArrayList<ExtensionComponent<SimplePersona>>();
List<ExtensionComponent<XmlBasedPersona>> r = new ArrayList<ExtensionComponent<XmlBasedPersona>>();

// locate personas from $HUDSON_HOME
try {
Expand All @@ -70,7 +61,7 @@ public <T> Collection<ExtensionComponent<T>> find(Class<T> type, Hudson hudson)
URL url = xml.toURI().toURL();
parsePersonaInto(url,
xml.getParent().toURI().toURL(),
xml.getParent().getRemote().substring(baseDir.getRemote().length()+1),r);
xml.getParent().getRemote().substring(baseDir.getRemote().length()+1).replace('\\','/'),r);
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Failed to load personas",e);
Expand All @@ -94,76 +85,16 @@ public <T> Collection<ExtensionComponent<T>> find(Class<T> type, Hudson hudson)
return (List)r;
}

/**
* Finds an image in ${imageBase}/${baseName}.* for some known extension
*/
private String findImage(URL imageBase, String imageBasePath, String baseName) throws IOException {
for (String ext : EXTENSIONS) {
try {
new URL(imageBase,baseName+ext).openStream().close();
// found it.
return imageBasePath+'/'+baseName+ext;
} catch (IOException e) {
// not found. try next
}
}
throw new IOException("No image found that matches "+imageBase+"/"+baseName+".*");
}

private void parsePersonaInto(URL xml, URL imageBase, String imageBasePath, Collection<ExtensionComponent<SimplePersona>> result) {
private void parsePersonaInto(URL xml, URL imageBase, String imageBasePath, Collection<ExtensionComponent<XmlBasedPersona>> result) {
try {
result.add(new ExtensionComponent<SimplePersona>(parsePersona(xml,imageBase,imageBasePath)));
result.add(new ExtensionComponent<XmlBasedPersona>(XmlBasedPersona.create(xml,imageBase,imageBasePath)));
} catch (DocumentException e) {
LOGGER.log(Level.SEVERE, "Faied to load a persona from "+xml,e);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Faied to load a persona from "+xml,e);
}
}

/**
* Parses a persona from an XML file.
*
* @param xml
* Location of the XML file.
* @param imageBase
* Base URL to find images like icon.png, success.jpg, and so on.
*/
private SimplePersona parsePersona(URL xml, final URL imageBase, final String imageBasePath) throws DocumentException, IOException {
Document d = new SAXReader().read(xml);
Element r = d.getRootElement();

List<String> quotes = new ArrayList<String>();
for (Element e : (List<Element>)r.elements("quote")) {
quotes.add(e.getTextTrim());
}
final String displayName = r.attributeValue("displayName");

final String icon = findImage(imageBase, imageBasePath, "icon");
final String success = findImage(imageBase, imageBasePath, "success");
final String failure = findImage(imageBase, imageBasePath, "failure");
final String other = findImage(imageBase, imageBasePath, "other");

return new SimplePersona(r.attributeValue("id"),quotes) {
@Override
public Image getImage(AbstractBuild<?,?> build) {
Result r = build.getResult();
if (r== Result.SUCCESS)
return new Image(icon,success);
if (r== Result.FAILURE)
return new Image(icon,failure);
return new Image(icon,other);
}

@Override
public Image getDefaultImage() {
return new Image(icon,success);
}

public String getDisplayName() {
return displayName;
}
};
}
private static final Logger LOGGER = Logger.getLogger(XmlPersonaFinder.class.getName());

private static final Logger LOGGER = Logger.getLogger(SimplePersonaFinder.class.getName());
}
52 changes: 52 additions & 0 deletions src/main/java/hudson/plugins/persona/xml/XmlPersonaReloader.java
@@ -0,0 +1,52 @@
package hudson.plugins.persona.xml;

import hudson.Extension;
import hudson.ExtensionComponent;
import hudson.ExtensionList;
import hudson.Util;
import hudson.model.Hudson;
import hudson.model.RootAction;
import hudson.plugins.persona.Persona;
import org.kohsuke.stapler.StaplerResponse;

import java.io.IOException;
import java.io.PrintWriter;

/**
* Exposes an URL to reload XML persona.
*
* @author Kohsuke Kawaguchi
*/
@Extension
public class XmlPersonaReloader implements RootAction {
public String getIconFileName() {
return null;
}

public String getDisplayName() {
return null;
}

public String getUrlName() {
return "reload-persona";
}

public void doIndex(StaplerResponse rsp) throws IOException {
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
rsp.setContentType("text/plain");
PrintWriter w = rsp.getWriter();

ExtensionList<Persona> all = Persona.all();

for (XmlBasedPersona p : Util.filter(all,XmlBasedPersona.class)) {
w.println("Reloaded "+p.xml);
}

// find new personas
for (ExtensionComponent<Persona> c : new XmlPersonaFinder().find(Persona.class, Hudson.getInstance())) {
XmlBasedPersona p = (XmlBasedPersona)c.getInstance();
if (Persona.byId(p.id)==null)
all.add(all.size(),p);
}
}
}

0 comments on commit 9440e95

Please sign in to comment.