All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.foreach.across.modules.filemanager.web.FileManagerBrowserController Maven / Gradle / Ivy

The newest version!
package com.foreach.across.modules.filemanager.web;

import com.foreach.across.core.annotations.ConditionalOnDevelopmentMode;
import com.foreach.across.modules.adminweb.annotations.AdminWebController;
import com.foreach.across.modules.adminweb.menu.AdminMenu;
import com.foreach.across.modules.adminweb.menu.AdminMenuEvent;
import com.foreach.across.modules.adminweb.ui.PageContentStructure;
import com.foreach.across.modules.filemanager.business.*;
import com.foreach.across.modules.filemanager.services.FileManager;
import com.foreach.across.modules.filemanager.services.FileRepository;
import com.foreach.across.modules.filemanager.services.FileRepositoryRegistry;
import com.foreach.across.modules.web.ui.elements.TemplateViewElement;
import lombok.Builder;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.context.event.EventListener;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.net.URLConnection;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Development mode controller which allows browsing all registered file repositories.
 *
 * @author Arne Vandamme
 * @since 1.4.0
 */
@SuppressWarnings("unused")
@AdminWebController
@RequestMapping("/ax/developer/fileManagerModule/fileManager")
@ConditionalOnDevelopmentMode
@RequiredArgsConstructor
class FileManagerBrowserController
{
	private final PageContentStructure page;
	private final FileRepositoryRegistry fileRepositoryRegistry;
	private final FileManager fileManager;

	@EventListener
	public void registerAdminMenu( AdminMenuEvent menuEvent ) {
		menuEvent.builder().item( "/ax/developer/fileManagerModule/fileManager", "File repositories" );
	}

	@GetMapping
	public String listFileRepositories( Model model ) {
		model.addAttribute( "repositories", fileRepositoryRegistry.listRepositories() );

		page.setPageTitle( "File repositories" );
		page.addChild( new TemplateViewElement( "th/FileManagerModule/dev/repository-browser :: listAllRepositories(${repositories})" ) );

		return PageContentStructure.TEMPLATE;
	}

	@GetMapping(params = { "repositoryId" })
	public String listResources( @RequestParam String repositoryId,
	                             @RequestParam(required = false, name = "folder") FolderDescriptor folderDescriptor,
	                             Model model,
	                             AdminMenu adminMenu ) {
		FileRepository repository = fileRepositoryRegistry.getRepository( repositoryId );
		model.addAttribute( "fileRepository", repository );

		FolderResource folder = folderDescriptor != null ? repository.getFolderResource( folderDescriptor ) : repository.getRootFolderResource();
		model.addAttribute(
				"fileRepositoryResources",
				folder.listResources( false ).stream().map( Resource::from ).sorted().collect( Collectors.toList() )
		);

		adminMenu.breadcrumbLeaf( repository.getRepositoryId() );

		LinkedList breadCrumb = new LinkedList<>();
		breadCrumb.add( folder );

		Optional parent = folder.getParentFolderResource();
		while ( parent.isPresent() ) {
			FolderResource f = parent.get();
			breadCrumb.addFirst( f );
			parent = f.getParentFolderResource();
		}

		model.addAttribute( "folderResourcePath", breadCrumb );

		page.setPageTitle( "File repositories: " + repository.getRepositoryId() );
		page.addChild(
				new TemplateViewElement(
						"th/FileManagerModule/dev/repository-browser :: listResources(${fileRepository},${folderResourcePath},${fileRepositoryResources})" )
		);

		return PageContentStructure.TEMPLATE;
	}

	@GetMapping("/{action:download|view}")
	@SneakyThrows
	public ResponseEntity downloadFile( @RequestParam(name = "file") FileDescriptor fileDescriptor,
	                                                                          @PathVariable String action ) {
		FileResource file = fileManager.getFileResource( fileDescriptor );

		HttpHeaders headers = new HttpHeaders();
		if ( "download".equals( action ) ) {
			headers.set( HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getFilename() );
			headers.setContentLength( file.contentLength() );
		}
		else {
			String contentType = URLConnection.guessContentTypeFromName( file.getFilename() );
			headers.set( HttpHeaders.CONTENT_TYPE, contentType );
		}

		return new ResponseEntity<>( file, headers, HttpStatus.OK );
	}

	@Data
	@Builder
	static class Resource implements Comparable
	{
		private String name;
		private boolean folder;
		private long contentLength;
		private Date lastModified;
		private FileRepositoryResourceDescriptor descriptor;

		public String readableFileSize() {
			if ( contentLength <= 0 ) {
				return "0";
			}
			final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
			int digitGroups = (int) ( Math.log10( contentLength ) / Math.log10( 1024 ) );
			return new DecimalFormat( "#,##0.#" ).format( contentLength / Math.pow( 1024, digitGroups ) ) + " " + units[digitGroups];
		}

		@Override
		public int compareTo( Resource o ) {
			int i = Boolean.compare( o.folder, folder );

			if ( i == 0 ) {
				i = name.compareToIgnoreCase( o.name );
			}

			return i;
		}

		@SneakyThrows
		static Resource from( FileRepositoryResource resource ) {
			if ( resource instanceof FolderResource ) {
				FolderResource folder = (FolderResource) resource;
				return Resource.builder().name( folder.getFolderName() ).folder( true ).descriptor( folder.getDescriptor() ).build();
			}

			FileResource fr = (FileResource) resource;
			return Resource.builder().name( fr.getFilename() ).descriptor( fr.getDescriptor() ).contentLength( fr.contentLength() )
			               .lastModified( fr.lastModified() > 0 ? new Date( fr.lastModified() ) : null )
			               .build();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy