/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.data; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.restlet.engine.io.IoUtils; import org.restlet.representation.Representation; import org.restlet.representation.StringRepresentation; import org.restlet.util.WrapperList; /** * List of URI references. * * @author Jerome Louvel */ public class ReferenceList extends WrapperList<Reference> { private static final String webPageStyle = "h1{border-bottom:1px solid silver;margin-bottom:10px;padding-bottom:10px;white-space:nowrap}" + "thead tr{font-weight:700}td.detailsColumn{-webkit-padding-start:2em;-moz-padding-start:2em;text-align:end;white-space:nowrap}" + "a.icon{-webkit-padding-start:1.5em;-moz-padding-start:1.5em;text-decoration:none}" + "a.icon:hover{text-decoration:underline}" + "a.file{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1QQWFA84umAmQgAAANpJREFUOMutkj1uhDAQhb8HSLtbISGfgZ+zbJkix0HmFhwhUdocBnMBGvqtTIqIFSReWKK8aix73nwzHrVt+zEMwwvH9FrX9TsA1trpqKy10+yUzME4jnjvAZB0LzXHkojjmDRNVyh3A+89zrlVwlKSqKrqVy/J8lAUxSZBSMny4ZLgp54iyPM8UPHGNJ2IomibAKDv+9VlWZbABbgB5/0WQgSSkC4PF2JF4JzbHN430c4vhAm0TyCJruuClefph4yCBCGT3T3Isoy/KDHGfDZNcz2SZIx547/0BVRRX7n8uT/sAAAAAElFTkSuQmCC) left top no-repeat}" + "a.dir{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHCSURBVDiNpZAxa5NRFIafc+9XLCni4BC6FBycMnbrLpkcgtDVX6C70D/g4lZX/4coxLlgxFkpiiSSUGm/JiXfveee45AmNlhawXc53HvPee55X+l2u/yPqt3d3Tfu/viatwt3fzIYDI5uBJhZr9fr3TMzzAx3B+D09PR+v98/7HQ6z5fNOWdCCGU4HH6s67oAVDlnV1UmkwmllBUkhMD29nYHeLuEAkyn06qU8qqu64MrgIyqYmZrkHa73drc3KTVahFjJITAaDRiPB4/XFlQVVMtHH5IzJo/P4EA4MyB+erWPQB7++zs7ccYvlU5Z08pMW2cl88eIXLZeDUpXzsBkNQ5eP1+p0opmaoCTgzw6fjs6gLLsp58FB60t0DcK1Ul54yIEIMQ43Uj68pquDmCeJVztpwzuBNE2LgBoMVpslHMCUEAFgDVxQbzVAiA+aK5uGPmmDtZF3VpoUm2ArhqQaRiUjcMf81p1G60UEVhcjZfAFTVUkrgkS+jc06mDX9nvq4YhJ9nlxZExMwMEaHJRutOdWuIIsJFUoBSuTvHJ4YIfP46unV4qdlsjsBRZRtb/XfHd5+C8+P7+J8BIoxFwovfRxYhnhxjpzEAAAAASUVORK5CYII=) left top no-repeat}" + "a.up{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIkSURBVDiNpZJNa1NBFIafM3Nr08SqWDDEQsFF7SIboeKie8mqiyB06y/QvdA/4MZd3fo3RBTiTigY7cYilVYpTUmoNrdpmzszd46LfLSB4sazGebMOc/5eEdqtRr/Y8ny8vIbVV294u1MVZ80m83NfwJijPV6vX4zxkiMEVUF4Pj4eK7RaGxUq9Xno2DvPcaY/ODg4HOapjlA4r3XEAKdToc8z8cQYwyVSqUKvBtBAXq9XpLn+as0TdcvATwhBGKME5ByuVwsFAoUi0WstRhjaLVatNvtxfEIIYQYQs7GR8dpdlEJBAClD/THXlUDrKyxsLJmrfmZeO/VOUcvU14+e4zIMPDypnTiBoALyvrrDwuJcy6GEADFGviy273cwOiY3LwV7pVLIKpJCAHvPSKCNYK1FynXCwmPFm+TGOHT99+k536gRohoVATRxHsfvfegihFhygrGCPcr11m6O4s1A2DtQZlv+ylf97q4oJiBfwAIYdBB3+XcuTHN0vwsM9csZy4fj6+qzM/NcKs0xdZel8zFMUBDyBFJ6KQZ2/snbO78YfVhZVRlsAuBzEfeNg+xRliYmxkAQgjROQdq2WmdcNTLUOCo58aKjJbpQiQ991gjHHaHI4hIjDEiImQ+UpxOAOj7fJh4QcmjUppOEBHOXADIE1Vl9ygiAls/WuPg7b3DSQmH7Yy+9elpH4HNJE6VGu93Z5+Csv+rfYXqV5sIbRHz4i/uqzb/IJewTwAAAABJRU5ErkJggg==) left top no-repeat}"; /** The list's identifier. */ private volatile Reference identifier; /** * Constructor. */ public ReferenceList() { super(); } /** * Constructor. * * @param initialCapacity * The initial list capacity. */ public ReferenceList(int initialCapacity) { super(new ArrayList<Reference>(initialCapacity)); } /** * Constructor. * * @param delegate * The delegate list. */ public ReferenceList(List<Reference> delegate) { super(delegate); } /** * Constructor from a "text/uri-list" representation. * * @param uriList * The "text/uri-list" representation to parse. * @throws IOException */ public ReferenceList(Representation uriList) throws IOException { BufferedReader br = null; try { br = new BufferedReader(uriList.getReader(), IoUtils.BUFFER_SIZE); String line = br.readLine(); // Checks if the list reference is specified as the first comment. if ((line != null) && line.startsWith("#")) { setIdentifier(new Reference(line.substring(1).trim())); line = br.readLine(); } while (line != null) { if (!line.startsWith("#")) { add(new Reference(line.trim())); } line = br.readLine(); } } finally { if (br != null) { br.close(); } } } /** * Creates then adds a reference at the end of the list. * * @param uri * The uri of the reference to add. * @return True (as per the general contract of the Collection.add method). */ public boolean add(String uri) { return add(new Reference(uri)); } /** * Returns the list identifier. * * @return The list identifier. */ public Reference getIdentifier() { return this.identifier; } /** * Returns a representation of the list in the "text/uri-list" format. * * @return A representation of the list in the "text/uri-list" format. * @see http://amundsen.com/hypermedia/urilist/ */ public Representation getTextRepresentation() { final StringBuilder sb = new StringBuilder(); if (getIdentifier() != null) { sb.append("# ").append(getIdentifier().toString()).append("\r\n"); } for (final Reference ref : this) { sb.append(ref.toString()).append("\r\n"); } return new StringRepresentation(sb.toString(), MediaType.TEXT_URI_LIST); } /** * Returns a representation of the list in "text/html" format. * * @return A representation of the list in "text/html" format. */ public Representation getWebRepresentation() { // Create a simple HTML list final StringBuilder sb = new StringBuilder(); sb.append("<html><head><meta charset=\"utf-8\">"); sb.append("<style>").append(webPageStyle).append("</style>"); sb.append("</head>"); sb.append("<body>"); if (getIdentifier() != null) { sb.append("<h1>Index of \"").append(getIdentifier().getPath()) .append("\"</h1>\n"); } sb.append("<table><thead><tr><td>Name</td></tr></thead>"); sb.append("<tbody>"); if (getIdentifier() != null) { Reference parentRef = getIdentifier().getParentRef(); if (!getIdentifier().equals(parentRef)) { sb.append("<tr><td><a class=\"icon up\" href=\""); sb.append(parentRef.toString()); sb.append("\">[parent directory]</a></td></tr>"); } } for (Reference ref : this) { String str = ref.toString(); if (str.endsWith("/")) { sb.append("<tr><td><a class=\"icon dir\" href=\""); } else { sb.append("<tr><td><a class=\"icon file\" href=\""); } sb.append(str); sb.append("\">"); sb.append(ref.getRelativeRef(getIdentifier())); sb.append("</td></tr>"); } sb.append("</tbody></table>\n"); sb.append("</body></html>\n"); return new StringRepresentation(sb.toString(), MediaType.TEXT_HTML); } /** * Sets the list reference. * * @param identifier * The list identifier. */ public void setIdentifier(Reference identifier) { this.identifier = identifier; } /** * Sets the list reference. * * @param identifier * The list identifier as a URI. */ public void setIdentifier(String identifier) { setIdentifier(new Reference(identifier)); } /** * Returns a view of the portion of this list between the specified * fromIndex, inclusive, and toIndex, exclusive. * * @param fromIndex * The start position. * @param toIndex * The end position (exclusive). * @return The sub-list. */ @Override public ReferenceList subList(int fromIndex, int toIndex) { // [ifndef gwt] line return new ReferenceList(getDelegate().subList(fromIndex, toIndex)); // [ifdef gwt] uncomment // return new // ReferenceList(org.restlet.engine.util.ListUtils.copySubList(getDelegate(), // fromIndex, toIndex)); // [enddef] } }