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