1    /*
2     * Copyright 2007 :torweg free software group
3     * 
4     * This program is free software: you can redistribute it and/or modify
5     * it under the terms of the GNU General Public License as published by
6     * the Free Software Foundation, either version 3 of the License, or
7     * (at your option) any later version.
8     * 
9     * This program is distributed in the hope that it will be useful,
10    * but WITHOUT ANY WARRANTY; without even the implied warranty of
11    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    * GNU General Public License for more details.
13    * 
14    * You should have received a copy of the GNU General Public License
15    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16    *
17    */
18   package org.torweg.pulse.vfs.filebrowser;
19   
20   import java.net.URI;
21   import java.text.DateFormat;
22   import java.util.Date;
23   
24   import javax.servlet.http.HttpServletRequest;
25   import javax.servlet.http.HttpServletResponse;
26   import javax.xml.bind.annotation.XmlAccessOrder;
27   import javax.xml.bind.annotation.XmlAccessType;
28   import javax.xml.bind.annotation.XmlAccessorOrder;
29   import javax.xml.bind.annotation.XmlAccessorType;
30   import javax.xml.bind.annotation.XmlRootElement;
31   import javax.xml.bind.annotation.XmlTransient;
32   
33   import org.jdom.Element;
34   import org.slf4j.Logger;
35   import org.slf4j.LoggerFactory;
36   import org.torweg.pulse.bundle.JDOMable;
37   import org.torweg.pulse.service.request.ServiceRequest;
38   import org.torweg.pulse.service.request.ServiceRequest.SessionMode;
39   import org.torweg.pulse.vfs.VirtualFile;
40   
41   /**
42    * contains common methods for descriptors of the {@code VirtualFileSystem} .
43    * 
44    * @author Thomas Weber
45    * @version $Revision: 1640 $
46    */
47   @XmlRootElement(name = "abstract-descriptor")
48   @XmlAccessorOrder(XmlAccessOrder.UNDEFINED)
49   @XmlAccessorType(XmlAccessType.FIELD)
50   public abstract class AbstractDescriptor implements JDOMable {
51   
52       /**
53        * href-element name.
54        */
55       private static final String HREF = "href";
56   
57       /**
58        * the logger.
59        */
60       private static final Logger LOGGER = LoggerFactory
61               .getLogger(AbstractDescriptor.class);
62   
63       /**
64        * the current request.
65        */
66       @XmlTransient
67       private ServiceRequest request;
68   
69       /**
70        * inserts the information of the given {@code VirtualFile} into the given
71        * {@code Element}.
72        * <p>
73        * This is a utility method for the JDOM deserialisation.
74        * </p>
75        * 
76        * @param e
77        *            the element
78        * @param f
79        *            the file
80        * @param req
81        *            the current request
82        * @return an {@code Element} with the information of the given {@code
83        *         VirtualFile} inserted
84        */
85       public final Element insertVirtualFileInformation(final Element e,
86               final VirtualFile f, final ServiceRequest req) {
87           e.setAttribute("id", Long.toString(f.getId()));
88           e.addContent(new Element("uri").setText(f.getURI().toASCIIString()));
89   
90           LOGGER.debug("file: {}  http-uri: {}", f, f.getHttpURI());
91   
92           if ((f.getHttpURI().getHost() != null) && (req != null)) {
93               shortenHttpURI(e, f, req);
94           } else if ((f.getHttpURI().getHost() != null) && (this.request != null)) {
95               shortenHttpURI(e, f, null);
96           } else {
97               e.addContent(new Element(HREF).setText(f.getHttpURI()
98                       .toASCIIString()));
99           }
100  
101          e.addContent(new Element("name").setText(f.getName()));
102          if (f.getName().lastIndexOf(".") > -1) {
103              e.addContent(new Element("extension").setText(f.getName()
104                      .substring(f.getName().lastIndexOf("."))));
105          } else {
106              e.addContent(new Element("extension"));
107          }
108          Element meta = new Element("meta");
109          // meta info: created
110          e.addContent(meta);
111          DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
112          Element created = new Element("created").setAttribute("date",
113                  dateFormat.format(new Date(f.created())));
114          created.setContent(new Element("creator").setAttribute("id",
115                  f.getCreator().getId().toString()).setText(
116                  f.getCreator().getName()));
117          meta.addContent(created);
118          // meta info: last modified
119          Element modified = new Element("modified").setAttribute("date",
120                  dateFormat.format(new Date(f.created())));
121          if (f.getLastModifier() != null) {
122              modified.setContent(new Element("modifier").setAttribute("id",
123                      f.getLastModifier().getId().toString()).setText(
124                      f.getLastModifier().getName()));
125          } else {
126              modified.setContent(new Element("modifier").setAttribute("id", "")
127                      .setText("unknown"));
128          }
129          meta.addContent(modified);
130          return e;
131      }
132  
133      /**
134       * tries to shorten the HTTP URI to the file by leaving out all parts before
135       * the path, if possible.
136       * 
137       * @param e
138       *            the element
139       * @param f
140       *            the file
141       * @param req
142       *            the request, if any
143       */
144      private void shortenHttpURI(final Element e, final VirtualFile f,
145              final ServiceRequest req) {
146          URI httpUri = f.getHttpURI();
147          HttpServletRequest servletRequest;
148          HttpServletResponse servletResponse;
149          if (req == null) {
150              servletRequest = this.request.getHttpServletRequest();
151              servletResponse = this.request.getHttpServletResponse();
152          } else {
153              servletRequest = req.getHttpServletRequest();
154              servletResponse = req.getHttpServletResponse();
155          }
156  
157          if (httpUri.getHost().equals(servletRequest.getServerName())
158                  && ((httpUri.getPort() == servletRequest.getServerPort()) || (httpUri
159                          .getPort() == -1))) {
160              StringBuilder shortUri = new StringBuilder(httpUri.getRawPath());
161              if (httpUri.getRawQuery() != null) {
162                  shortUri.append("?").append(httpUri.getRawQuery());
163              }
164              if (httpUri.getRawFragment() != null) {
165                  shortUri.append("#").append(httpUri.getRawFragment());
166              }
167              if (req.getSessionMode() == SessionMode.USE_URL_ENCODED) {
168                  e.addContent(new Element(HREF).setText(servletResponse
169                          .encodeURL(shortUri.toString().replace("+", "%20"))));
170              } else {
171                  e.addContent(new Element(HREF).setText(shortUri.toString()
172                          .replace("+", "%20")));
173              }
174              LOGGER.debug("shortened URI: {}", shortUri);
175          } else {
176              e.addContent(new Element(HREF).setText(httpUri.toASCIIString()
177                      .replace("+", "%20")));
178          }
179      }
180  
181      /**
182       * sets the current {@code ServiceRequest} for the descriptor.
183       * 
184       * @param r
185       *            the current {@code ServiceRequest}
186       */
187      public final void setServiceRequest(final ServiceRequest r) {
188          this.request = r;
189      }
190  
191      /**
192       * returns the current {@code ServiceRequest}.
193       * 
194       * @return the current {@code ServiceRequest}
195       */
196      protected final ServiceRequest getServiceRequest() {
197          return this.request;
198      }
199  }
200