001/* 002 * Copyright 2015 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.serverdirectory; 017 018import java.util.Collection; 019import java.util.Collections; 020import java.util.HashMap; 021import java.util.Map; 022import java.util.Set; 023 024import org.apache.avalon.framework.logger.LogEnabled; 025import org.apache.avalon.framework.logger.Logger; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.avalon.framework.service.Serviceable; 029import org.apache.commons.lang.StringUtils; 030import org.apache.excalibur.source.Source; 031import org.apache.excalibur.source.SourceException; 032import org.apache.excalibur.source.SourceResolver; 033import org.apache.excalibur.source.TraversableSource; 034 035import org.ametys.runtime.i18n.I18nizableText; 036import org.ametys.runtime.model.Enumerator; 037 038/** 039 * Enumerate sub-directories from root directories defined in configuration's parameters 040 */ 041public class ServerDirectoryEnumerator implements Serviceable, Enumerator<String>, org.ametys.runtime.parameter.Enumerator, LogEnabled 042{ 043 private SourceResolver _sourceResolver; 044 private Logger _logger; 045 046 public void service(ServiceManager manager) throws ServiceException 047 { 048 _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 049 } 050 051 @Override 052 public void enableLogging(Logger logger) 053 { 054 _logger = logger; 055 } 056 057 @Override 058 public I18nizableText getEntry(String value) throws Exception 059 { 060 return new I18nizableText(value); 061 } 062 063 @Override 064 public Map<String, I18nizableText> getTypedEntries() throws Exception 065 { 066 Map<String, I18nizableText> directories = new HashMap<>(); 067 068 Set<String> locations = ServerDirectoryHelper.getRootServerDirectoryPaths(); 069 070 for (String location : locations) 071 { 072 Source source = null; 073 try 074 { 075 source = _sourceResolver.resolveURI(location, "file://", null); 076 077 if (source.exists()) 078 { 079 directories.putAll(_getDirectories(source)); 080 } 081 else 082 { 083 _logger.error("The path '" + location + "' is not an existing server directory. It will be ignored"); 084 } 085 086 } 087 catch (Exception e) 088 { 089 throw new IllegalArgumentException("Cannot enumerate subdirectories for location: <" + location + ">", e); 090 } 091 finally 092 { 093 _sourceResolver.release(source); 094 } 095 } 096 097 return directories; 098 } 099 100 private Map<String, I18nizableText> _getDirectories(Source source) throws SourceException 101 { 102 Map<String, I18nizableText> directories = new HashMap<>(); 103 104 if (source instanceof TraversableSource) 105 { 106 TraversableSource tSource = (TraversableSource) source; 107 108 if (tSource.isCollection()) 109 { 110 String path = StringUtils.substringAfter(source.getURI(), source.getScheme() + ":/"); 111 directories.put(source.getURI(), new I18nizableText(path)); 112 113 Collection<Source> childrenSources = tSource.getChildren(); 114 for (Source childSource : childrenSources) 115 { 116 directories.putAll(_getDirectories(childSource)); 117 } 118 } 119 } 120 121 return directories; 122 } 123 124 // TODO NEWATTRIBUTEAPI: remove this method when org.ametys.runtime.parameter.Enumerator will be removed 125 public Map<Object, I18nizableText> getEntries() throws Exception 126 { 127 Map<Object, I18nizableText> result = new HashMap<>(); 128 for (Map.Entry<String, I18nizableText> entry : getTypedEntries().entrySet()) 129 { 130 result.put(entry.getKey(), entry.getValue()); 131 } 132 return Collections.unmodifiableMap(result); 133 } 134 135 @Override 136 // TODO NEWATTRIBUTEAPI: remove this method when org.ametys.runtime.parameter.Enumerator will be removed 137 public Map<String, Object> getConfiguration() 138 { 139 return Collections.EMPTY_MAP; 140 } 141}