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.archiva.repository.storage.StorageAsset;
23  import org.apache.commons.lang3.StringUtils;
24  import org.apache.jackrabbit.webdav.io.OutputContext;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  import java.io.IOException;
29  import java.io.PrintWriter;
30  import java.nio.file.Path;
31  import java.nio.file.Paths;
32  import java.text.DateFormat;
33  import java.util.ArrayList;
34  import java.util.Comparator;
35  import java.util.Date;
36  import java.util.List;
37  import java.util.Locale;
38  import java.util.Map;
39  import java.util.SortedMap;
40  import java.util.TreeMap;
41  
42  /**
43   */
44  public class IndexWriter
45  {
46  
47      private static final Logger log = LoggerFactory.getLogger( IndexWriter.class );
48  
49      private final String logicalResource;
50  
51      private final List<StorageAsset> repositoryAssets;
52  
53  
54      private final boolean isVirtual;
55  
56      public IndexWriter( StorageAsset reference, String logicalResource )
57      {
58          this.repositoryAssets = new ArrayList<>(  );
59          this.repositoryAssets.add(reference);
60          this.logicalResource = logicalResource;
61          this.isVirtual = false;
62      }
63  
64      public IndexWriter( List<StorageAsset> localResources, String logicalResource )
65      {
66          this.logicalResource = logicalResource;
67          this.repositoryAssets = localResources;
68          this.isVirtual = true;
69      }
70  
71      public void write( OutputContext outputContext )
72      {
73          outputContext.setModificationTime( new Date().getTime() );
74          outputContext.setContentType( "text/html" );
75          outputContext.setETag( "" ); // skygo ETag MRM-1127 seems to be fixed
76          if ( outputContext.hasStream() )
77          {
78              PrintWriter writer = new PrintWriter( outputContext.getOutputStream() );
79              writeDocumentStart( writer );
80              try
81              {
82                  writeHyperlinks( writer );
83              }
84              catch ( IOException e )
85              {
86                  log.error("Could not write hyperlinks {}", e.getMessage(), e);
87              }
88              writeDocumentEnd( writer );
89              writer.flush();
90              writer.close();
91          }
92      }
93  
94      private void writeDocumentStart( PrintWriter writer )
95      {
96          writer.println("<!DOCTYPE html>");
97          writer.println( "<html>" );
98          writer.println( "<head>" );
99          writer.println( "<title>Collection: /" + logicalResource + "</title>" );
100         writer.println( "<style type=\"text/css\">" );
101         writer.println( "ul{list-style:none;}" ); 
102         
103         StringBuilder relative = new StringBuilder("../../");
104         if ( logicalResource != null && logicalResource.length() > 0 )
105         {
106             String tmpRelative = StringUtils.replace( logicalResource, "\\", "/" );
107             for (int i=0;i<tmpRelative.split("/").length;i++) 
108             {
109                 relative.append("../");
110             }
111         }
112         writer.println( ".file{background:url(" + relative.toString() + "images/package-x-generic.png) no-repeat scroll 0 0 transparent;}" );
113         writer.println( ".folder{background:url(" + relative.toString() + "images/folder.png) no-repeat scroll 0 0 transparent;}" );
114         writer.println( "a{color:#0088CC;text-decoration: none;padding-left:20px;}" );
115         writer.println( ".collection tr:nth-child(odd){background-color:#fafafa;}" );
116         writer.println( "tr td:nth-child(2){width:150px;color:#cc8800;text-align:right;}" );
117         writer.println( "tr td:nth-child(3){width:150px;color:#0000cc;text-align:center;}" );
118         writer.println( "th td:nth-child(2){width:150px;}" );
119         writer.println( "th td:nth-child(3){width:150px;}" );
120         writer.println( "</style>" );
121         writer.println( "<link rel=\"shortcut icon\" href=\"../../favicon.ico\"/>" );
122         writer.println( "</head>" );
123         writer.println( "<body>" );
124         writer.println( "<h3>Collection: /" + logicalResource + "</h3>" );
125 
126         //Check if not root
127         if ( logicalResource != null && logicalResource.length() > 0 )
128         {
129             Path file = Paths.get( logicalResource );
130             String parentName = file.getParent() == null ? "/" : file.getParent().toString();
131 
132             //convert to unix path in case archiva is hosted on windows
133             parentName = StringUtils.replace( parentName, "\\", "/" );
134 
135             writer.println( "<ul>" );
136             writer.println( "<li><a class=\"folder\" href=\"../\">" + parentName + "</a> <i><small>(Parent)</small></i></li>" );
137             writer.println( "</ul>" );
138         }
139 
140         writer.println( "<table class=\"collection\">" );
141         writer.println( "<tr><th>Name</th><th>Size (Bytes)</th><th>Last Modified</th></tr>" );
142     }
143 
144     private void writeDocumentEnd( PrintWriter writer )
145     {
146         writer.println( "</table>" );
147         writer.println( "</body>" );
148         writer.println( "</html>" );
149     }
150 
151     private void writeHyperlinks( PrintWriter writer ) throws IOException
152     {
153         if ( !isVirtual )
154         {
155             for ( StorageAsset localResource : repositoryAssets )
156             {
157                 localResource.list().stream().sorted(
158                     Comparator.comparing( StorageAsset::getName )
159                 ).forEach( asset -> {
160                     writeHyperlink( writer, asset.getName(), asset.getModificationTime().toEpochMilli(), asset.getSize(),
161                         asset.isContainer() );
162                 } );
163             }
164         }
165         else
166         {
167             // virtual repository - filter unique directories
168             SortedMap<String, StorageAsset> uniqueChildFiles = new TreeMap<>();
169             for ( StorageAsset resource : repositoryAssets )
170             {
171                 List<StorageAsset> files = resource.list();
172                 for ( StorageAsset file : files )
173                 {
174                     // the first entry wins
175                     if (!uniqueChildFiles.containsKey( file.getName() )) {
176                         uniqueChildFiles.put(file.getName(), file);
177                     }
178                 }
179             }
180             for ( Map.Entry<String, StorageAsset> entry : uniqueChildFiles.entrySet())
181             {
182                 final StorageAsset asset = entry.getValue();
183                  writeHyperlink( writer, asset.getName(), asset.getModificationTime().toEpochMilli(),
184                             asset.getSize(), asset.isContainer());
185             }
186         }
187     }
188 
189     private static String fileDateFormat( long date ) 
190     {
191         DateFormat dateFormatter = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault() );
192         Date aDate = new Date( date );
193         return dateFormatter.format( aDate );
194     }
195     
196     private void writeHyperlink( PrintWriter writer, String resourceName, long lastModified, long fileSize, boolean directory )
197     {
198         if ( directory )
199         {
200             writer.println( "<tr><td><a class=\"folder\" href=\"" + resourceName + "/\">" + resourceName + "</a></td><td>&nbsp;</td><td>&nbsp;</td></tr>" );
201         }
202         else
203         {
204             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>" );
205         }
206     }
207 }