This project has retired. For details please refer to its Attic page.
IndexWriter xref
View Javadoc
1   package org.apache.archiva.webdav.util;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.jackrabbit.webdav.DavResource;
24  import org.apache.jackrabbit.webdav.io.OutputContext;
25  
26  import java.io.File;
27  import java.io.PrintWriter;
28  import java.text.DateFormat;
29  import java.util.ArrayList;
30  import java.util.Arrays;
31  import java.util.Collections;
32  import java.util.Date;
33  import java.util.HashMap;
34  import java.util.List;
35  import java.util.Locale;
36  import java.util.Map;
37  
38  /**
39   */
40  public class IndexWriter
41  {
42      private final String logicalResource;
43  
44      private final List<File> localResources;
45  
46      private final boolean isVirtual;
47  
48      public IndexWriter( DavResource resource, File localResource, String logicalResource )
49      {
50          this.localResources = new ArrayList<>();
51          this.localResources.add( localResource );
52          this.logicalResource = logicalResource;
53          this.isVirtual = false;
54      }
55  
56      public IndexWriter( DavResource resource, List<File> localResources, String logicalResource )
57      {
58          this.logicalResource = logicalResource;
59          this.localResources = localResources;
60          this.isVirtual = true;
61      }
62  
63      public void write( OutputContext outputContext )
64      {
65          outputContext.setModificationTime( new Date().getTime() );
66          outputContext.setContentType( "text/html" );
67          outputContext.setETag( "" ); // skygo ETag MRM-1127 seems to be fixed
68          if ( outputContext.hasStream() )
69          {
70              PrintWriter writer = new PrintWriter( outputContext.getOutputStream() );
71              writeDocumentStart( writer );
72              writeHyperlinks( writer );
73              writeDocumentEnd( writer );
74              writer.flush();
75              writer.close();
76          }
77      }
78  
79      private void writeDocumentStart( PrintWriter writer )
80      {
81          writer.println("<!DOCTYPE html>");
82          writer.println( "<html>" );
83          writer.println( "<head>" );
84          writer.println( "<title>Collection: /" + logicalResource + "</title>" );
85          writer.println( "<style type=\"text/css\">" );
86          writer.println( "ul{list-style:none;}" ); 
87          
88          StringBuilder relative = new StringBuilder("../../");
89          if ( logicalResource != null && logicalResource.length() > 0 )
90          {
91              String tmpRelative = StringUtils.replace( logicalResource, "\\", "/" );
92              for (int i=0;i<tmpRelative.split("/").length;i++) 
93              {
94                  relative.append("../");
95              }
96          }
97          writer.println( ".file{background:url(" + relative.toString() + "images/package-x-generic.png) no-repeat scroll 0 0 transparent;}" );
98          writer.println( ".folder{background:url(" + relative.toString() + "images/folder.png) no-repeat scroll 0 0 transparent;}" );
99          writer.println( "a{color:#0088CC;text-decoration: none;padding-left:20px;}" );
100         writer.println( ".collection tr:nth-child(odd){background-color:#fafafa;}" );
101         writer.println( "tr td:nth-child(2){width:150px;color:#cc8800;text-align:right;}" );
102         writer.println( "tr td:nth-child(3){width:150px;color:#0000cc;text-align:center;}" );
103         writer.println( "th td:nth-child(2){width:150px;}" );
104         writer.println( "th td:nth-child(3){width:150px;}" );
105         writer.println( "</style>" );
106         writer.println( "<link rel=\"shortcut icon\" href=\"../../favicon.ico\"/>" );
107         writer.println( "</head>" );
108         writer.println( "<body>" );
109         writer.println( "<h3>Collection: /" + logicalResource + "</h3>" );
110 
111         //Check if not root
112         if ( logicalResource != null && logicalResource.length() > 0 )
113         {
114             File file = new File( logicalResource );
115             String parentName = file.getParent() == null ? "/" : file.getParent();
116 
117             //convert to unix path in case archiva is hosted on windows
118             parentName = StringUtils.replace( parentName, "\\", "/" );
119 
120             writer.println( "<ul>" );
121             writer.println( "<li><a class=\"folder\" href=\"../\">" + parentName + "</a> <i><small>(Parent)</small></i></li>" );
122             writer.println( "</ul>" );
123         }
124 
125         writer.println( "<table class=\"collection\">" );
126         writer.println( "<tr><th>Name</th><th>Size (Bytes)</th><th>Last Modified</th></tr>" );
127     }
128 
129     private void writeDocumentEnd( PrintWriter writer )
130     {
131         writer.println( "</table>" );
132         writer.println( "</body>" );
133         writer.println( "</html>" );
134     }
135 
136     private void writeHyperlinks( PrintWriter writer )
137     {
138         if ( !isVirtual )
139         {
140             for ( File localResource : localResources )
141             {
142                 List<File> files = new ArrayList<>( Arrays.asList( localResource.listFiles() ) );
143                 Collections.sort( files );
144 
145                 for ( File file : files )
146                 {
147                     writeHyperlink( writer, file.getName(), file.lastModified(), file.length(), file.isDirectory() );
148                 }
149             }
150         }
151         else
152         {
153             // virtual repository - filter unique directories
154             Map<String, List<String>> uniqueChildFiles = new HashMap<>();
155             List<String> sortedList = new ArrayList<>();
156             for ( File resource : localResources )
157             {
158                 List<File> files = new ArrayList<>( Arrays.asList( resource.listFiles() ) );
159                 for ( File file : files )
160                 {
161                     List<String> mergedChildFiles = new ArrayList<>();
162                     if ( uniqueChildFiles.get( file.getName() ) == null )
163                     {
164                         mergedChildFiles.add( file.getAbsolutePath() );
165                     }
166                     else
167                     {
168                         mergedChildFiles = uniqueChildFiles.get( file.getName() );
169                         if ( !mergedChildFiles.contains( file.getAbsolutePath() ) )
170                         {
171                             mergedChildFiles.add( file.getAbsolutePath() );
172                         }
173                     }
174                     uniqueChildFiles.put( file.getName(), mergedChildFiles );
175                     sortedList.add( file.getName() );
176                 }
177             }
178 
179             Collections.sort( sortedList );
180             List<String> written = new ArrayList<>();
181             for ( String fileName : sortedList )
182             {
183                 List<String> childFilesFromMap = uniqueChildFiles.get( fileName );
184                 for ( String childFilePath : childFilesFromMap )
185                 {
186                     File childFile = new File( childFilePath );
187                     if ( !written.contains( childFile.getName() ) )
188                     {
189                         written.add( childFile.getName() );
190                         writeHyperlink( writer, fileName, childFile.lastModified(), childFile.length(), childFile.isDirectory() );
191                     }
192                 }
193             }
194         }
195     }
196 
197     private static String fileDateFormat( long date ) 
198     {
199         DateFormat dateFormatter = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault() );
200         Date aDate = new Date( date );
201         return dateFormatter.format( aDate );
202     }
203     
204     private void writeHyperlink( PrintWriter writer, String resourceName, long lastModified, long fileSize, boolean directory )
205     {
206         if ( directory )
207         {
208             writer.println( "<tr><td><a class=\"folder\" href=\"" + resourceName + "/\">" + resourceName + "</a></td><td>&nbsp;</td><td>&nbsp;</td></tr>" );
209         }
210         else
211         {
212             writer.println( "<tr><td><a class=\"file\" href=\"" + resourceName + "\">" + resourceName + "</a></td><td class=\"size\">" + fileSize + "&nbsp;&nbsp;</td><td class=\"date\">" + fileDateFormat( lastModified ) + "</td></tr>" );
213         }
214     }
215 }