This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.webdav.util;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.commons.lang.StringUtils;
023import org.apache.jackrabbit.webdav.DavResource;
024import org.apache.jackrabbit.webdav.io.OutputContext;
025
026import java.io.File;
027import java.io.PrintWriter;
028import java.text.DateFormat;
029import java.util.ArrayList;
030import java.util.Arrays;
031import java.util.Collections;
032import java.util.Date;
033import java.util.HashMap;
034import java.util.List;
035import java.util.Locale;
036import java.util.Map;
037
038/**
039 */
040public class IndexWriter
041{
042    private final String logicalResource;
043
044    private final List<File> localResources;
045
046    private final boolean isVirtual;
047
048    public IndexWriter( DavResource resource, File localResource, String logicalResource )
049    {
050        this.localResources = new ArrayList<>();
051        this.localResources.add( localResource );
052        this.logicalResource = logicalResource;
053        this.isVirtual = false;
054    }
055
056    public IndexWriter( DavResource resource, List<File> localResources, String logicalResource )
057    {
058        this.logicalResource = logicalResource;
059        this.localResources = localResources;
060        this.isVirtual = true;
061    }
062
063    public void write( OutputContext outputContext )
064    {
065        outputContext.setModificationTime( new Date().getTime() );
066        outputContext.setContentType( "text/html" );
067        outputContext.setETag( "" ); // skygo ETag MRM-1127 seems to be fixed
068        if ( outputContext.hasStream() )
069        {
070            PrintWriter writer = new PrintWriter( outputContext.getOutputStream() );
071            writeDocumentStart( writer );
072            writeHyperlinks( writer );
073            writeDocumentEnd( writer );
074            writer.flush();
075            writer.close();
076        }
077    }
078
079    private void writeDocumentStart( PrintWriter writer )
080    {
081        writer.println("<!DOCTYPE html>");
082        writer.println( "<html>" );
083        writer.println( "<head>" );
084        writer.println( "<title>Collection: /" + logicalResource + "</title>" );
085        writer.println( "<style type=\"text/css\">" );
086        writer.println( "ul{list-style:none;}" ); 
087        
088        StringBuilder relative = new StringBuilder("../../");
089        if ( logicalResource != null && logicalResource.length() > 0 )
090        {
091            String tmpRelative = StringUtils.replace( logicalResource, "\\", "/" );
092            for (int i=0;i<tmpRelative.split("/").length;i++) 
093            {
094                relative.append("../");
095            }
096        }
097        writer.println( ".file{background:url(" + relative.toString() + "images/package-x-generic.png) no-repeat scroll 0 0 transparent;}" );
098        writer.println( ".folder{background:url(" + relative.toString() + "images/folder.png) no-repeat scroll 0 0 transparent;}" );
099        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}