1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.genericattributes.service.upload;
35
36 import java.util.ArrayList;
37 import java.util.Iterator;
38 import java.util.List;
39 import java.util.Locale;
40 import java.util.Map;
41 import java.util.concurrent.ConcurrentHashMap;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
44
45 import javax.servlet.http.HttpServletRequest;
46 import javax.servlet.http.HttpSession;
47
48 import org.apache.commons.fileupload.FileItem;
49 import org.apache.commons.lang3.StringUtils;
50
51 import fr.paris.lutece.plugins.asynchronousupload.service.AbstractAsynchronousUploadHandler;
52 import fr.paris.lutece.plugins.genericattributes.business.Entry;
53 import fr.paris.lutece.plugins.genericattributes.business.EntryHome;
54 import fr.paris.lutece.plugins.genericattributes.business.GenericAttributeError;
55 import fr.paris.lutece.plugins.genericattributes.service.entrytype.EntryTypeServiceManager;
56 import fr.paris.lutece.plugins.genericattributes.service.entrytype.IEntryTypeService;
57 import fr.paris.lutece.portal.service.i18n.I18nService;
58 import fr.paris.lutece.portal.service.util.AppException;
59 import fr.paris.lutece.util.filesystem.UploadUtil;
60
61
62
63
64 public abstract class AbstractGenAttUploadHandler extends AbstractAsynchronousUploadHandler
65 {
66 private static final String PREFIX_ENTRY_ID = IEntryTypeService.PREFIX_ATTRIBUTE;
67 private static final Pattern PATTERN_PREFIX_ENTRY_ID = Pattern.compile( "[^0-9]+([0-9]+)$" );
68
69
70 private static final String ERROR_MESSAGE_UNKNOWN_ERROR = "genericattributes.message.unknownError";
71
72
73
74 private static Map<String, Map<String, List<FileItem>>> _mapAsynchronousUpload = new ConcurrentHashMap<>( );
75
76
77
78
79 @Override
80 public String canUploadFiles( HttpServletRequest request, String strFieldName, List<FileItem> listFileItemsToUpload, Locale locale )
81 {
82 if ( StringUtils.isNotBlank( strFieldName ) && ( strFieldName.length( ) > PREFIX_ENTRY_ID.length( ) ) )
83 {
84 String sessionId = getCustomSessionId( request.getSession( ) );
85 initMap( sessionId, strFieldName );
86
87 String strIdEntry = getEntryIdFromFieldName( strFieldName );
88
89 if ( StringUtils.isEmpty( strIdEntry ) || !StringUtils.isNumeric( strIdEntry ) )
90 {
91 return I18nService.getLocalizedString( ERROR_MESSAGE_UNKNOWN_ERROR, locale );
92 }
93
94 int nIdEntry = Integer.parseInt( strIdEntry );
95 Entry entry = EntryHome.findByPrimaryKey( nIdEntry );
96
97 List<FileItem> listUploadedFileItems = getListUploadedFiles( strFieldName, request.getSession( ) );
98
99 if ( entry != null )
100 {
101 GenericAttributeError error = EntryTypeServiceManager.getEntryTypeService( entry ).canUploadFiles( entry, listUploadedFileItems,
102 listFileItemsToUpload, locale );
103
104 if ( error != null )
105 {
106 return error.getErrorMessage( );
107 }
108
109 return null;
110 }
111 }
112
113 return I18nService.getLocalizedString( ERROR_MESSAGE_UNKNOWN_ERROR, locale );
114 }
115
116
117
118
119 @Override
120 public List<FileItem> getListUploadedFiles( String strFieldName, HttpSession session )
121 {
122 if ( StringUtils.isBlank( strFieldName ) )
123 {
124 throw new AppException( "id field name is not provided for the current file upload" );
125 }
126
127 String sessionId = getCustomSessionId( session );
128
129 initMap( sessionId, strFieldName );
130
131
132 Map<String, List<FileItem>> mapFileItemsSession = _mapAsynchronousUpload.get( sessionId );
133
134 return mapFileItemsSession.get( strFieldName );
135 }
136
137
138
139
140 @Override
141 public void addFileItemToUploadedFilesList( FileItem fileItem, String strFieldName, HttpServletRequest request )
142 {
143
144
145 String strFileName = UploadUtil.cleanFileName( fileItem.getName( ).trim( ) );
146
147 String sessionId = getCustomSessionId( request.getSession( ) );
148 initMap( sessionId, strFieldName );
149
150
151 List<FileItem> uploadedFiles = getListUploadedFiles( strFieldName, request.getSession( ) );
152
153 if ( uploadedFiles != null )
154 {
155 boolean bNew = true;
156
157 if ( !uploadedFiles.isEmpty( ) )
158 {
159 Iterator<FileItem> iterUploadedFiles = uploadedFiles.iterator( );
160
161 while ( bNew && iterUploadedFiles.hasNext( ) )
162 {
163 FileItem uploadedFile = iterUploadedFiles.next( );
164 String strUploadedFileName = UploadUtil.cleanFileName( uploadedFile.getName( ).trim( ) );
165
166
167
168 bNew = !( StringUtils.equals( strUploadedFileName, strFileName ) && ( uploadedFile.getSize( ) == fileItem.getSize( ) ) );
169 }
170 }
171
172 if ( bNew )
173 {
174 uploadedFiles.add( fileItem );
175 }
176 }
177 }
178
179 @Override
180 public void removeSessionFiles( HttpSession session )
181 {
182 String sessionId = (String) session.getAttribute( PARAM_CUSTOM_SESSION_ID );
183 if ( sessionId != null )
184 {
185 _mapAsynchronousUpload.remove( sessionId );
186 }
187
188 }
189
190
191
192
193
194
195
196
197 protected String buildFieldName( String strIdEntry )
198 {
199 return PREFIX_ENTRY_ID + strIdEntry;
200 }
201
202
203
204
205
206
207
208
209 protected String getEntryIdFromFieldName( String strFieldName )
210 {
211 if ( StringUtils.isEmpty( strFieldName ) || ( strFieldName.length( ) < PREFIX_ENTRY_ID.length( ) ) )
212 {
213 return null;
214 }
215
216 Matcher matcher = PATTERN_PREFIX_ENTRY_ID.matcher( strFieldName );
217 if ( matcher.find( ) )
218 {
219 return matcher.group( 1 );
220 }
221
222 return null;
223 }
224
225
226
227
228
229
230
231
232
233 private void initMap( String strSessionId, String strFieldName )
234 {
235
236 Map<String, List<FileItem>> mapFileItemsSession = _mapAsynchronousUpload.get( strSessionId );
237
238
239 if ( mapFileItemsSession == null )
240 {
241 synchronized( this )
242 {
243
244 mapFileItemsSession = _mapAsynchronousUpload.computeIfAbsent( strSessionId, s -> new ConcurrentHashMap<>( ) );
245 }
246 }
247
248 mapFileItemsSession.computeIfAbsent( strFieldName, s -> new ArrayList<>( ) );
249 }
250 }