/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.bsc.confluence.model; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import org.apache.commons.io.IOUtils; import org.bsc.confluence.ConfluenceService.Storage; import org.bsc.markdown.ToConfluenceSerializer; import org.pegdown.PegDownProcessor; import org.pegdown.ast.Node; import org.pegdown.ast.RootNode; import rx.functions.Func2; //import org.slf4j.Logger; //import org.slf4j.LoggerFactory; /** * * @author bsorrentino */ @XmlRootElement( name="site", namespace = Site.NAMESPACE) public class Site { public static final String NAMESPACE = "https://github.com/bsorrentino/maven-confluence-plugin"; /** * */ protected static final java.util.Stack<Site> _SITE = new java.util.Stack<Site>(); //private static final Logger LOGGER = LoggerFactory.getLogger(Site.class); /** * * @param is * @return */ static java.io.InputStream processMarkdown( final java.io.InputStream is, final String homePageTitle ) throws IOException { final char[] contents = IOUtils.toCharArray(is); final PegDownProcessor p = new PegDownProcessor(ToConfluenceSerializer.extensions()); final RootNode root = p.parseMarkdown(contents); ToConfluenceSerializer ser = new ToConfluenceSerializer() { @Override protected void notImplementedYet(Node node) { final int lc[] = ToConfluenceSerializer.lineAndColFromNode( new String(contents), node); throw new UnsupportedOperationException( String.format("Node [%s] not supported yet. line=[%d] col=[%d]", node.getClass().getSimpleName(), lc[0], lc[1] )); } @Override protected String getHomePageTitle() { return homePageTitle; } }; root.accept( ser ); return new java.io.ByteArrayInputStream( ser.toString().getBytes() ); } /** * * @param uri * @return * @throws Exception */ public static <T> T processUri( final java.net.URI uri, final String homePageTitle, final Func2<java.io.InputStream,Storage.Representation,T> onSuccess ) throws /*ProcessUri*/Exception { if( uri == null ) { throw new IllegalArgumentException( "uri is null!" ); } String scheme = uri.getScheme(); if (scheme == null) { throw new Exception( String.format("uri [%s] is invalid!", String.valueOf(uri) )); } final String source = uri.getRawSchemeSpecificPart(); final String path = uri.getRawPath(); final boolean isMarkdown = (path !=null && path.endsWith(".md")); final boolean isStorage = (path !=null && (path.endsWith(".xml") || path.endsWith(".xhtml"))); final Storage.Representation representation = (isStorage) ? Storage.Representation.STORAGE : Storage.Representation.WIKI; java.io.InputStream result = null; if ("classpath".equalsIgnoreCase(scheme)) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); result = cl.getResourceAsStream(source); if (result == null) { //getLog().warn(String.format("resource [%s] doesn't exist in context classloader", source)); cl = Site.class.getClassLoader(); final java.io.InputStream is = cl.getResourceAsStream(source); result = (isMarkdown) ? processMarkdown(is, homePageTitle) : is; if (result == null) { throw new Exception(String.format("resource [%s] doesn't exist in classloader", source)); } } } else { try { java.net.URL url = uri.toURL(); final java.io.InputStream is = url.openStream(); result = (isMarkdown) ? processMarkdown(is, homePageTitle) : is; } catch (IOException e) { throw new Exception(String.format("error opening url [%s]!", source), e); } } /* if (LOGGER.isDebugEnabled()) { String resultString = IOUtils.toString(result); LOGGER.debug("Result: {}", resultString); result = new ByteArrayInputStream(resultString.getBytes()); } */ return onSuccess.call(result, representation); } /** * class Source */ @XmlType(namespace = Site.NAMESPACE) protected static class Source { protected transient final Site site; private java.net.URI uri; @XmlAttribute public final java.net.URI getUri() { if( uri!=null && !uri.isAbsolute() && site.getBasedir()!=null ) { return site.getBasedir().toURI().resolve(uri); } return uri; } public final void setUri(java.net.URI value) { if (null == value) { throw new IllegalArgumentException("uri is null"); } //if (!value.isAbsolute()) { // throw new IllegalArgumentException("uri is not absolute!"); //} this.uri = value; } String name; @XmlAttribute public String getName() { return name; } public void setName(String name) { this.name = name; } public Source() { this.site = _SITE.peek(); } @Override public String toString() { return getClass().getSimpleName() + ": " + getName() + " - " + String.valueOf(getUri()); } protected void validateSource() { if (null == uri) { throw new IllegalStateException("uri is null"); } } } /** * class Attachment */ @XmlType(name="attachment", namespace = Site.NAMESPACE) public static class Attachment extends Source { public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream"; public static final String DEFAULT_VERSION = "0"; String contentType; @XmlAttribute public String getContentType() { return contentType; } public void setContentType(String contentType) { this.contentType = contentType; } String comment; @XmlAttribute public String getComment() { if (comment == null) { if (getName() == null) { setComment("attached by maven-confluence-plugin"); } else { setComment(String.format("%s - attached by maven-confluence-plugin", getName())); } } return comment; } public void setComment(String comment) { this.comment = comment; } String version; @XmlAttribute public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public boolean hasBeenUpdatedFrom( java.util.Date date) { if( date != null ) { validateSource(); final java.net.URI _uri = super.getUri(); if ( !_uri.isAbsolute() || "file".equals(_uri.getScheme())) { java.io.File f = new java.io.File(_uri); return f.lastModified() > date.getTime(); } } return true; } public Attachment() { this.contentType = DEFAULT_CONTENT_TYPE; this.version = DEFAULT_VERSION; } } /** * class Page */ @XmlType(name="page", namespace = Site.NAMESPACE) public static class Page extends Source { java.util.List<Attachment> attachments; @Deprecated public File getSource() { validateSource(); final java.net.URI _uri = super.getUri(); if ( !_uri.isAbsolute() && !"file".equals(_uri.getScheme())) { throw new IllegalArgumentException("uri not represent a file"); } return new java.io.File(_uri); } private java.util.List<String> labels; @XmlElement(name="label") public java.util.List<String> getLabels() { if (null == labels) { synchronized (this) { labels = new java.util.ArrayList<String>(); } } return labels; } public void setLabels(java.util.List<String> labels) { this.labels = labels; } private Page parent; @XmlTransient public final void setParent( Page p ) { parent = p; } @XmlTransient public final java.util.List<String> getComputedLabels() { if (site!=null ) { java.util.List<String> _labels = site.getLabels(); if( _labels!=null && !_labels.isEmpty()) { _labels = new java.util.ArrayList<String>(_labels); _labels.addAll( getLabels() ); return _labels; } } return getLabels(); } java.util.List<Page> children; @XmlElement(name = "child") public java.util.List<Page> getChildren() { if (null == children) { synchronized (this) { children = ChildListProxy.newInstance(this); /*children = new java.util.ArrayList<Page>();*/ } } return children; } @XmlElement(name = "attachment") public List<Attachment> getAttachments() { if (null == attachments) { synchronized (this) { attachments = new java.util.ArrayList<Attachment>(); } } return attachments; } public java.net.URI getUri( String ext) { if (getUri() == null) { if (getName() == null) { throw new IllegalStateException("name is null"); } setUri( site.getBasedir().toURI().resolve( getName().concat(ext)) ); //final String path = String.format("src/site/confluence/%s%s", getName(), ext); //setUri(new java.io.File(project.getBasedir(), path).toURI()); } return getUri(); } boolean ignoreVariables = false; @XmlAttribute(name="ignore-variables") public boolean isIgnoreVariables() { return ignoreVariables; } public void setIgnoreVariables(boolean value) { this.ignoreVariables = value; } @XmlElement(name = "generated") protected List<Generated> generateds; /** * Gets the value of the generateds property. * * <p> * This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a <CODE>set</CODE> method for the generateds property. * * <p> * For example, to add a new item, do as follows: * <pre> * getGenerateds().add(newItem); * </pre> * * * <p> * Objects of the following type(s) are allowed in the list * {@link Generated } * * */ public List<Page.Generated> getGenerateds() { if (generateds == null) { generateds = new ArrayList<Generated>(); } return this.generateds; } @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "") public static class Generated { @XmlAttribute(name = "ref") protected String ref; /** * Obtient la valeur de la propriété ref. * * @return * possible object is * {@link String } * */ public String getRef() { return ref; } /** * Définit la valeur de la propriété ref. * * @param value * allowed object is * {@link String } * */ public void setRef(String value) { this.ref = value; } } } public Site() { _SITE.push(this); } private transient java.io.File basedir; public File getBasedir() { return basedir; } public void setBasedir(File basedir) { this.basedir = basedir; } private java.util.List<String> labels; @XmlElement(name="label") public java.util.List<String> getLabels() { if (null == labels) { synchronized (this) { labels = new java.util.ArrayList<String>(); } } return labels; } public void setLabels(java.util.List<String> labels) { this.labels = labels; } Page home; @XmlElement(name="home",required = true) public Page getHome() { return home; } public void setHome(Page home) { this.home = home; } private void printSource( PrintStream out, int level, char c, final Source source ) { for( int i=0; i <level; ++i ) { System.out.print(c); } out.print( " " ); out.println( source ); } private void printChildren( PrintStream out, int level, Page parent ) { printSource( out, level, '-', parent ); for( Attachment attach : parent.getAttachments() ) { printSource( out, level+1, '#', attach ); } for( Page child : parent.getChildren() ) { printChildren( out, level+1, child ); } } public void print( PrintStream out ) { out.println( "Site" ); if( !getLabels().isEmpty() ) { out.println(" Labels"); for( String label : getLabels() ) { out.printf( " %s\n", label ); } } printChildren( out, 0, getHome() ); } }