You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2017/01/19 14:54:35 UTC

svn commit: r1779474 - in /openmeetings/application: branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/ branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/ branches/3.2.x/openmeetings-web/src...

Author: solomax
Date: Thu Jan 19 14:54:34 2017
New Revision: 1779474

URL: http://svn.apache.org/viewvc?rev=1779474&view=rev
Log:
[OPENMEETINGS-1534] room video upload is fixed

Modified:
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java
    openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java
    openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java Thu Jan 19 14:54:34 2017
@@ -19,8 +19,8 @@
 package org.apache.openmeetings.core.converter;
 
 import static org.apache.openmeetings.core.data.record.listener.async.BaseStreamWriter.TIME_TO_WAIT_FOR_FRAME;
-import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_JPG;
 import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_FLV;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_JPG;
 import static org.apache.openmeetings.util.OmFileHelper.getRecordingMetaData;
 import static org.apache.openmeetings.util.OmFileHelper.getStreamsSubDir;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
@@ -66,7 +66,7 @@ public abstract class BaseConverter {
 		path += app;
 		return path;
 	}
-	
+
 	public String getPathToFFMPEG() {
 		return getPath("ffmpeg_path", "ffmpeg");
 	}
@@ -82,7 +82,7 @@ public abstract class BaseConverter {
 	protected boolean isUseOldStyleFfmpegMap() {
 		return "1".equals(configurationDao.getConfValue("use.old.style.ffmpeg.map.option", String.class, "0"));
 	}
-	
+
 	protected File getStreamFolder(Recording recording) {
 		return getStreamsSubDir(recording.getRoomId());
 	}
@@ -94,11 +94,11 @@ public abstract class BaseConverter {
 	protected double diffSeconds(Date from, Date to) {
 		return diffSeconds(diff(from, to));
 	}
-	
+
 	protected double diffSeconds(long val) {
 		return ((double)val) / 1000;
 	}
-	
+
 	protected String formatMillis(long millis) {
 		long hours = TimeUnit.MILLISECONDS.toHours(millis);
 		millis -= TimeUnit.HOURS.toMillis(hours);
@@ -112,33 +112,33 @@ public abstract class BaseConverter {
 	protected void updateDuration(Recording r) {
 		r.setDuration(formatMillis(diff(r.getRecordEnd(), r.getRecordStart())));
 	}
-	
+
 	protected void deleteFileIfExists(File f) {
 		if (f.exists()) {
 			f.delete();
 		}
 	}
-	
+
 	protected String[] mergeAudioToWaves(List<File> waveFiles, File wav) throws IOException {
 		List<String> argv = new ArrayList<String>();
-		
+
 		argv.add(getPathToSoX());
 		argv.add("-m");
 		for (File arg : waveFiles) {
 			argv.add(arg.getCanonicalPath());
 		}
 		argv.add(wav.getCanonicalPath());
-		
+
 		return argv.toArray(new String[0]);
 	}
-	
+
 	protected void stripAudioFirstPass(Recording recording, List<ConverterProcessResult> returnLog,
 			List<File> waveFiles, File streamFolder)
 	{
 		stripAudioFirstPass(recording, returnLog, waveFiles, streamFolder
 				, metaDataDao.getAudioMetaDataByRecording(recording.getId()));
 	}
-	
+
 	private String[] addSoxPad(List<ConverterProcessResult> returnLog, String job, double length, double position, File inFile, File outFile) throws IOException {
 		//FIXME need to check this
 		if (length < 0 || position < 0) {
@@ -153,12 +153,12 @@ public abstract class BaseConverter {
 		returnLog.add(ProcessHelper.executeScript(job, argv));
 		return argv;
 	}
-	
+
 	private static File getMetaFlvSer(RecordingMetaData metaData) {
 		File metaDir = getStreamsSubDir(metaData.getRecording().getRoomId());
 		return new File(metaDir, metaData.getStreamName() + ".flv.ser");
 	}
-	
+
 	public static void printMetaInfo(RecordingMetaData metaData, String prefix) {
 		if (log.isDebugEnabled()) {
 			log.debug(String.format("### %s:: recording id %s; stream with id %s; current status: %s ", prefix, metaData.getRecording().getId()
@@ -169,7 +169,7 @@ public abstract class BaseConverter {
 			log.debug(String.format("### %s:: Ser file [%s] exists ? %s; size: %s, lastModified: %s ", prefix, metaSer.getPath(), metaSer.exists(), metaSer.length(), metaSer.lastModified()));
 		}
 	}
-	
+
 	protected RecordingMetaData waitForTheStream(long metaId) throws InterruptedException {
 		RecordingMetaData metaData = metaDataDao.get(metaId);
 		if (metaData.getStreamStatus() != Status.STOPPED) {
@@ -178,9 +178,9 @@ public abstract class BaseConverter {
 			long maxTimestamp = 0;
 			while(true) {
 				log.trace("### Stream not yet written Thread Sleep - " + metaId);
-				
+
 				metaData = metaDataDao.get(metaId);
-				
+
 				if (metaData.getStreamStatus() == Status.STOPPED) {
 					printMetaInfo(metaData, "Stream now written");
 					log.debug("### Thread continue ... " );
@@ -217,13 +217,13 @@ public abstract class BaseConverter {
 				if (++counter % 1000 == 0) {
 					printMetaInfo(metaData, "Still waiting");
 				}
-				
+
 				Thread.sleep(100L);
 			}
 		}
 		return metaData;
 	}
-	
+
 	protected void stripAudioFirstPass(Recording recording,
 			List<ConverterProcessResult> returnLog,
 			List<File> waveFiles, File streamFolder,
@@ -232,7 +232,7 @@ public abstract class BaseConverter {
 			// Init variables
 			log.debug("### meta Data Number - " + metaDataList.size());
 			log.debug("###################################################");
-	
+
 			for (RecordingMetaData metaData : metaDataList) {
 				long metaId = metaData.getId();
 				log.debug("### processing metadata: " + metaId);
@@ -240,49 +240,48 @@ public abstract class BaseConverter {
 					log.debug("Stream has not been started, error in recording " + metaId);
 					continue;
 				}
-				
+
 				metaData = waitForTheStream(metaId);
-	
+
 				File inputFlvFile = new File(streamFolder, OmFileHelper.getName(metaData.getStreamName(), EXTENSION_FLV));
-	
+
 				File outputWav = new File(streamFolder, metaData.getStreamName() + "_WAVE.wav");
-	
+
 				metaData.setWavAudioData(outputWav.getName());
-	
-				
+
 				log.debug("FLV File Name: {} Length: {} ", inputFlvFile.getName(), inputFlvFile.length());
-	
+
 				if (inputFlvFile.exists()) {
 					String[] argv = new String[] {
 							getPathToFFMPEG(), "-y"
 							, "-i", inputFlvFile.getCanonicalPath()
 							, "-af", "aresample=32k:min_comp=0.001:min_hard_comp=0.100000"
 							, outputWav.getCanonicalPath()};
-	
+
 					returnLog.add(ProcessHelper.executeScript("stripAudioFromFLVs", argv));
 				}
-	
+
 				if (outputWav.exists() && outputWav.length() != 0) {
 					metaData.setAudioValid(true);
 					// Strip Wave to Full Length
 					File outputGapFullWav = outputWav;
-	
+
 					// Fix Start/End in Audio
 					List<RecordingMetaDelta> metaDeltas = metaDeltaDao.getByMetaId(metaId);
-	
+
 					int counter = 0;
-	
+
 					for (RecordingMetaDelta metaDelta : metaDeltas) {
 						File inputFile = outputGapFullWav;
-	
+
 						// Strip Wave to Full Length
 						String hashFileGapsFullName = metaData.getStreamName() + "_GAP_FULL_WAVE_" + counter + ".wav";
 						outputGapFullWav = new File(streamFolder, hashFileGapsFullName);
-	
+
 						metaDelta.setWaveOutPutName(hashFileGapsFullName);
-	
+
 						String[] argv_sox = null;
-	
+
 						if (metaDelta.getDeltaTime() != null) {
 							double gapSeconds = diffSeconds(metaDelta.getDeltaTime());
 							if (metaDelta.isStartPadding()) {
@@ -291,43 +290,43 @@ public abstract class BaseConverter {
 								argv_sox = addSoxPad(returnLog, "fillGap", 0, gapSeconds, inputFile, outputGapFullWav);
 							}
 						}
-	
+
 						if (argv_sox != null) {
 							log.debug("START fillGap ################# Delta-ID :: " + metaDelta.getId());
-	
+
 							metaDeltaDao.update(metaDelta);
 							counter++;
 						} else {
 							outputGapFullWav = inputFile;
 						}
 					}
-	
+
 					// Strip Wave to Full Length
 					String hashFileFullName = metaData.getStreamName() + "_FULL_WAVE.wav";
 					File outputFullWav = new File(streamFolder, hashFileFullName);
-	
+
 					// Calculate delta at beginning
 					double startPad = diffSeconds(metaData.getRecordStart(), recording.getRecordStart());
-	
+
 					// Calculate delta at ending
 					double endPad = diffSeconds(recording.getRecordEnd(), metaData.getRecordEnd());
-	
+
 					addSoxPad(returnLog, "addStartEndToAudio", startPad, endPad, outputGapFullWav, outputFullWav);
-	
+
 					// Fix for Audio Length - Invalid Audio Length in Recorded Files
 					// Audio must match 100% the Video
 					log.debug("############################################");
 					log.debug("Trim Audio to Full Length -- Start");
-	
+
 					if (!outputFullWav.exists()) {
 						throw new Exception("Audio File does not exist , could not extract the Audio correctly");
 					}
 					metaData.setFullWavAudioData(hashFileFullName);
-	
+
 					// Finally add it to the row!
 					waveFiles.add(outputFullWav);
 				}
-	
+
 				metaDataDao.update(metaData);
 			}
 		} catch (Exception err) {
@@ -341,7 +340,7 @@ public abstract class BaseConverter {
 
 	protected List<String> addMp4OutParams(Recording r, List<String> argv, String mp4path) throws IOException {
 		argv.addAll(Arrays.asList(
-				"-c:v", "libx264",
+				"-c:v", "h264", //
 				"-crf", "24",
 				"-pix_fmt", "yuv420p",
 				"-preset", "medium",
@@ -349,7 +348,7 @@ public abstract class BaseConverter {
 				"-c:a", "libfaac",
 				"-c:a", "libfdk_aac",
 				"-ar", "22050",
-				"-b:a", "32k", //FIXME add quality constants 
+				"-b:a", "32k", //FIXME add quality constants
 				"-s", getDimensions(r), //
 				mp4path
 				));

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java Thu Jan 19 14:54:34 2017
@@ -44,7 +44,7 @@ public class FlvExplorerConverter extend
 	// Spring loaded Beans
 	@Autowired
 	private FileExplorerItemDao fileDao;
-	
+
 	private static class FlvDimension {
 		public FlvDimension(int width, int height) {
 			this.width = width;
@@ -66,8 +66,13 @@ public class FlvExplorerConverter extend
 				res = ProcessHelper.executeScript("Info ID :: " + f.getId(), args);
 				res.setExitCode(0); //normal code is 1, ffmpeg requires output file
 			} else {
-				String[] args = new String[] { getPathToFFMPEG(), "-y", "-i", f.getFile(ext).getCanonicalPath(),
-						"-c:a", "aac", "-c:v", "h264", "-pix_fmt", "yuv420p", mp4.getCanonicalPath() };
+				String[] args = new String[] { getPathToFFMPEG(), "-y"
+						, "-i", f.getFile(ext).getCanonicalPath() //
+						, "-c:v", "h264" //
+						, "-c:a", "libfaac" //
+						, "-c:a", "libfdk_aac" //
+						, "-pix_fmt", "yuv420p" //
+						, mp4.getCanonicalPath() };
 				res = ProcessHelper.executeScript("uploadFLV ID :: " + f.getId(), args);
 
 			}
@@ -93,16 +98,16 @@ public class FlvExplorerConverter extend
 
 		return logs;
 	}
-	
+
 	private static FlvDimension getFlvDimension(String txt) throws Exception {
 		Matcher matcher = p.matcher(txt);
-		
+
 		while (matcher.find()) {
 			String foundResolution = txt.substring(matcher.start(), matcher.end());
 			String[] resultions = foundResolution.split("x");
 			return new FlvDimension(Integer.valueOf(resultions[0]).intValue(), Integer.valueOf(resultions[1]).intValue());
 		}
-		
+
 		return new FlvDimension(100, 100); // will return 100x100 for non-video to be able to play
 	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java Thu Jan 19 14:54:34 2017
@@ -19,7 +19,7 @@
 package org.apache.openmeetings.util;
 
 import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_JPG;
-import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
+
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
@@ -45,7 +45,7 @@ public class StoredFile {
 
 	private static final Set<String> chartExtensions = new HashSet<>(Arrays.asList("xchart"));
 
-	private static final Set<String> asIsExtensions = new HashSet<>(Arrays.asList(EXTENSION_MP4, EXTENSION_JPG, "xchart"));
+	private static final Set<String> asIsExtensions = new HashSet<>(Arrays.asList(EXTENSION_JPG, "xchart")); //mp4 removed to get video size
 
 	private final String name;
 	private final String ext;
@@ -97,7 +97,7 @@ public class StoredFile {
 		String[] mime = type.split("/");
 		return mime[0];
 	}
-	
+
 	public boolean isImage() {
 		String mime = getMimeType(this);
 		return MIME_IMAGE.equals(mime);

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Thu Jan 19 14:54:34 2017
@@ -90,6 +90,8 @@ import org.apache.wicket.request.cycle.R
 import org.apache.wicket.request.mapper.info.PageComponentInfo;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.wicket.resource.DynamicJQueryResourceReference;
 import org.apache.wicket.util.collections.ConcurrentHashSet;
 import org.slf4j.Logger;
 import org.springframework.web.context.WebApplicationContext;
@@ -101,7 +103,7 @@ import org.wicketstuff.dashboard.web.Das
 public class Application extends AuthenticatedWebApplication implements IApplication {
 	private static final Logger log = getLogger(Application.class, webAppRootKey);
 	private static boolean isInstalled;
-	private static ConcurrentHashMap<String, Client> ONLINE_USERS = new ConcurrentHashMap<>(); 
+	private static ConcurrentHashMap<String, Client> ONLINE_USERS = new ConcurrentHashMap<>();
 	private static ConcurrentHashMap<String, Client> INVALID_SESSIONS = new ConcurrentHashMap<>();
 	private static ConcurrentHashMap<Long, Set<String>> ROOMS = new ConcurrentHashMap<>();
 	//additional maps for faster searching should be created
@@ -119,14 +121,15 @@ public class Application extends Authent
 		wicketApplicationName = super.getName();
 		getSecuritySettings().setAuthenticationStrategy(new OmAuthenticationStrategy());
 		getApplicationSettings().setAccessDeniedPage(AccessDeniedPage.class);
-		
-		//Add custom resource loader at the beginning, so it will be checked first in the 
-		//chain of Resource Loaders, if not found it will search in Wicket's internal 
+
+		//Add custom resource loader at the beginning, so it will be checked first in the
+		//chain of Resource Loaders, if not found it will search in Wicket's internal
 		//Resource Loader for a the property key
 		getResourceSettings().getStringResourceLoaders().add(0, new LabelResourceLoader());
-		
+		getJavaScriptLibrarySettings().setJQueryReference(new JavaScriptResourceReference(DynamicJQueryResourceReference.class, DynamicJQueryResourceReference.VERSION_2));
+
 		super.init();
-		
+
 		// register some widgets
 		dashboardContext = new DashboardContext();
 		dashboardContext.setDashboardPersister(new UserDashboardPersister());
@@ -141,7 +144,7 @@ public class Application extends Authent
 		DashboardSettings dashboardSettings = DashboardSettings.get();
 		dashboardSettings.setIncludeJQuery(false);
 		dashboardSettings.setIncludeJQueryUI(false);
-		
+
 		getRootRequestMapperAsCompound().add(new NoVersionMapper(getHomePage()));
 		getRootRequestMapperAsCompound().add(new NoVersionMapper("notinited", NotInitedPage.class));
 		getRootRequestMapperAsCompound().add(new NoVersionMapper(HASH_MAPPING, HashPage.class));
@@ -160,7 +163,7 @@ public class Application extends Authent
 		public NoVersionMapper(final Class<? extends IRequestablePage> pageClass) {
 			this("/", pageClass);
 		}
-		
+
 		public NoVersionMapper(String mountPath, final Class<? extends IRequestablePage> pageClass) {
 			super(mountPath, pageClass, new PageParametersEncoder());
 		}
@@ -169,7 +172,7 @@ public class Application extends Authent
 		protected void encodePageComponentInfo(Url url, PageComponentInfo info) {
 			//Does nothing
 		}
-		
+
 		@Override
 		public Url mapHandler(IRequestHandler requestHandler) {
 			if (requestHandler instanceof ListenerInterfaceRequestHandler || requestHandler instanceof BookmarkableListenerInterfaceRequestHandler) {
@@ -183,7 +186,7 @@ public class Application extends Authent
 	public static OmAuthenticationStrategy getAuthenticationStrategy() {
 		return (OmAuthenticationStrategy)get().getSecuritySettings().getAuthenticationStrategy();
 	}
-	
+
 	@Override
 	public Class<? extends Page> getHomePage() {
 		return MainPage.class;
@@ -198,27 +201,27 @@ public class Application extends Authent
 	public Class<? extends WebPage> getSignInPageClass() {
 		return SignInPage.class;
 	}
-	
+
 	public static Application get() {
 		return (Application) WebApplication.get();
 	}
-	
+
 	public static DashboardContext getDashboardContext() {
 		return get().dashboardContext;
 	}
-	
+
 	public static void addOnlineUser(Client c) {
 		log.debug("Adding online client: {}, room: {}", c.getUid(), c.getRoomId());
 		ONLINE_USERS.put(c.getUid(), c);
 	}
-	
+
 	public static void removeOnlineUser(Client c) {
 		if (c != null) {
 			log.debug("Removing online client: {}, room: {}", c.getUid(), c.getRoomId());
 			ONLINE_USERS.remove(c.getUid());
 		}
 	}
-	
+
 	@Override
 	public org.apache.openmeetings.db.entity.room.Client updateClient(org.apache.openmeetings.db.entity.room.Client rcl) {
 		if (rcl == null) {
@@ -259,11 +262,11 @@ public class Application extends Authent
 		}
 		return rcl;
 	}
-	
+
 	public static Client getOnlineClient(String uid) {
 		return uid == null ? null : ONLINE_USERS.get(uid);
 	}
-	
+
 	public static boolean isUserOnline(Long userId) {
 		boolean isUserOnline = false;
 		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
@@ -271,7 +274,7 @@ public class Application extends Authent
 				isUserOnline = true;
 				break;
 			}
-		} 
+		}
 		return isUserOnline;
 	}
 
@@ -289,11 +292,11 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static int getClientsSize() {
 		return ONLINE_USERS.size();
 	}
-	
+
 	public static Client getClientByKeys(Long userId, String sessionId) {
 		Client client = null;
 		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
@@ -302,10 +305,10 @@ public class Application extends Authent
 				client = c;
 				break;
 			}
-		} 
+		}
 		return client;
 	}
-	
+
 	@Override
 	public void invalidateClient(Long userId, String sessionId) {
 		Client client = getClientByKeys(userId, sessionId);
@@ -316,24 +319,24 @@ public class Application extends Authent
 			}
 		}
 	}
-	
+
 	public static boolean isInvaldSession(String sessionId) {
 		return sessionId == null ? false : INVALID_SESSIONS.containsKey(sessionId);
 	}
-	
+
 	public static void removeInvalidSession(String sessionId) {
 		if (sessionId != null){
 			INVALID_SESSIONS.remove(sessionId);
 		}
 	}
-	
+
 	public static Client addUserToRoom(Client c) {
 		log.debug("Adding online room client: {}, room: {}", c.getUid(), c.getRoomId());
 		ROOMS.putIfAbsent(c.getRoomId(), new ConcurrentHashSet<String>());
 		ROOMS.get(c.getRoomId()).add(c.getUid());
 		return c;
 	}
-	
+
 	public static Client removeUserFromRoom(Client c) {
 		log.debug("Removing online room client: {}, room: {}", c.getUid(), c.getRoomId());
 		if (c.getRoomId() != null) {
@@ -347,7 +350,7 @@ public class Application extends Authent
 		}
 		return c;
 	}
-	
+
 	public static List<Client> getRoomClients(Long roomId) {
 		List<Client> clients = new ArrayList<>();
 		if (roomId != null) {
@@ -363,7 +366,7 @@ public class Application extends Authent
 		}
 		return clients;
 	}
-	
+
 	public static Set<Long> getUserRooms(Long userId) {
 		Set<Long> result = new HashSet<>();
 		for (Entry<Long, Set<String>> me : ROOMS.entrySet()) {
@@ -376,7 +379,7 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static boolean isUserInRoom(long roomId, long userId) {
 		Set<String> clients = ROOMS.get(roomId);
 		if (clients != null) {
@@ -388,7 +391,7 @@ public class Application extends Authent
 		}
 		return false;
 	}
-	
+
 	//TODO need more safe way FIXME
 	public <T> T _getBean(Class<T> clazz) {
 		WebApplicationContext wac = getWebApplicationContext(getServletContext());
@@ -410,15 +413,15 @@ public class Application extends Authent
 		}
 		return loc;
 	}
-	
+
 	public static String getString(String key, final long languageId) {
 		return getString(key, getLocale(languageId));
 	}
-	
+
 	public static String getString(long id, final long languageId) {
 		return getString(id, getLocale(languageId));
 	}
-	
+
 	public static String getString(long id, final Locale loc) {
 		return getString("" + id, loc);
 	}
@@ -452,7 +455,7 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static <T> T getBean(Class<T> clazz) {
 		if (InitializationContainer.initComplete) {
 			if (!isInstalled()) {
@@ -463,7 +466,7 @@ public class Application extends Authent
 			throw new RestartResponseException(NotInitedPage.class);
 		}
 	}
-	
+
 	@Override
 	public <T> T getOmBean(Class<T> clazz) { //FIXME hack for email templates support (should be in separate module for now
 		return Application.getBean(clazz);
@@ -504,12 +507,12 @@ public class Application extends Authent
 		}
 		return link;
 	}
-	
+
 	@Override
 	public String getOmInvitationLink(Invitation i) { //FIXME hack for email templates support (should be in separate module for now
 		return getInvitationLink(i);
 	}
-	
+
 	public static String urlForPage(Class<? extends Page> clazz, PageParameters pp) {
 		RequestCycle rc = RequestCycle.get();
 		return rc.getUrlRenderer().renderFullUrl(Url.parse(getBean(ConfigurationDao.class).getBaseUrl() + rc.urlFor(clazz, pp)));
@@ -524,7 +527,7 @@ public class Application extends Authent
 	public String getOmString(long id) {
 		return getString(id);
 	}
-	
+
 	@Override
 	public String getOmString(long id, long languageId) {
 		return getString(id, languageId);

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java Thu Jan 19 14:54:34 2017
@@ -18,11 +18,15 @@
  */
 package org.apache.openmeetings.web.common;
 
+import java.io.Serializable;
+import java.util.function.BiConsumer;
+
 import org.apache.wicket.ajax.AjaxEventBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
 import org.apache.wicket.markup.html.border.Border;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.EmptyPanel;
 import org.apache.wicket.model.Model;
 
 import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
@@ -33,25 +37,40 @@ import com.googlecode.wicket.jquery.ui.w
 
 public abstract class ConfirmableAjaxBorder extends Border {
 	private static final long serialVersionUID = 1L;
+	private static final String DIALOG_ID = "dialog";
 	private final Form<?> form = new Form<>("form");
-	private final Form<?> userForm;
-	private final AbstractFormDialog<?> dialog;
+	private final ConfirmableBorderDialog dialog;
 
 	public ConfirmableAjaxBorder(String id, String title, String message) {
-		this(id, title, message, null);
+		this(id, title, message, null, null);
 	}
-	
+
 	public ConfirmableAjaxBorder(String id, String title, String message, Form<?> form) {
+		this(id, title, message, form, null);
+	}
+
+	public ConfirmableAjaxBorder(String id, String title, String message, ConfirmableBorderDialog dialog) {
+		this(id, title, message, null, dialog);
+	}
+
+	public ConfirmableAjaxBorder(String id, String title, String message, Form<?> userForm, ConfirmableBorderDialog dialog) {
 		super(id, Model.of(message));
-		dialog = newFormDialog("dialog", title, message);
-		this.userForm = form;
+		if (dialog == null) {
+			this.dialog = new ConfirmableBorderDialog(DIALOG_ID, title, message, userForm == null ? form : userForm);
+			form.add(this.dialog);
+		} else {
+			this.dialog = dialog;
+			form.add(new EmptyPanel(DIALOG_ID));
+		}
+		this.dialog.setSubmitHandler((BiConsumer<AjaxRequestTarget,Form<?>> & Serializable)(t, f)->onSubmit(t, f));
+		this.dialog.setErrorHandler((BiConsumer<AjaxRequestTarget,Form<?>> & Serializable)(t, f)->onError(t, f));
 		setOutputMarkupId(true);
 	}
 
 	public AbstractFormDialog<?> getDialog() {
 		return dialog;
 	}
-	
+
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();
@@ -63,27 +82,33 @@ public abstract class ConfirmableAjaxBor
 				super.updateAjaxAttributes(attributes);
 				ConfirmableAjaxBorder.this.updateAjaxAttributes(attributes);
 			}
-			
+
 			@Override
 			protected void onEvent(AjaxRequestTarget target) {
-				dialog.open(target);
+				if (isClickable()) {
+					dialog.open(target);
+				}
 			}
 		});
-		addToBorder(form.add(dialog));
+		addToBorder(form);
+	}
+
+	protected boolean isClickable() {
+		return true;
 	}
 
 	/**
 	 * Gives a chance to the specializations to modify the attributes.
-	 * 
+	 *
 	 * @param attributes attributes
 	 */
 	protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
 	}
-	
+
 	protected void onEvent(AjaxRequestTarget target) {
 		dialog.open(target);
 	}
-	
+
 	/**
 	 * Triggered when the form is submitted, but the validation failed
 	 *
@@ -101,39 +126,52 @@ public abstract class ConfirmableAjaxBor
 	 */
 	protected abstract void onSubmit(AjaxRequestTarget target, Form<?> form);
 
-	/**
-	 * Create the dialog instance<br/>
-	 * <b>Warning:</b> to be overridden with care!
-	 *
-	 * @param id the markupId
-	 * @param title the title of the dialog
-	 * @param message the message to be displayed
-	 * @return the dialog instance
-	 */
-	protected AbstractFormDialog<?> newFormDialog(String id, String title, String message) {
-		return new MessageFormDialog(id, title, message, DialogButtons.OK_CANCEL, DialogIcon.WARN) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public DialogButton getSubmitButton() {
-				return this.findButton(OK);
-			}
-
-			@Override
-			public Form<?> getForm() {
-				return userForm == null ? form : userForm;
-			}
-
-			@Override
-			protected void onError(AjaxRequestTarget target) {
-				super.close(target, null); // closes the dialog on error.
-				ConfirmableAjaxBorder.this.onError(target, this.getForm());
-			}
-
-			@Override
-			protected void onSubmit(AjaxRequestTarget target) {
-				ConfirmableAjaxBorder.this.onSubmit(target, this.getForm());
+	public static class ConfirmableBorderDialog extends MessageFormDialog {
+		private static final long serialVersionUID = 1L;
+		private Form<?> form;
+		private BiConsumer<AjaxRequestTarget,Form<?>> submitHandler = null;
+		private BiConsumer<AjaxRequestTarget,Form<?>> errorHandler = null;
+
+		public ConfirmableBorderDialog(String id, String title, String message) {
+			this(id, title, message, null);
+		}
+
+		public ConfirmableBorderDialog(String id, String title, String message, Form<?> form) {
+			super(id, title, message, DialogButtons.OK_CANCEL, DialogIcon.WARN);
+			this.form = form;
+		}
+
+		public void setSubmitHandler(BiConsumer<AjaxRequestTarget, Form<?>> submitHandler) {
+			this.submitHandler = submitHandler;
+		}
+
+		public void setErrorHandler(BiConsumer<AjaxRequestTarget, Form<?>> errorHandler) {
+			this.errorHandler = errorHandler;
+		}
+
+		@Override
+		public DialogButton getSubmitButton() {
+			return this.findButton(OK);
+		}
+
+		@Override
+		public Form<?> getForm() {
+			return this.form;
+		}
+
+		@Override
+		protected void onError(AjaxRequestTarget target) {
+			super.close(target, null); // closes the dialog on error.
+			if (errorHandler != null) {
+				errorHandler.accept(target, this.getForm());
+			}
+		}
+
+		@Override
+		protected void onSubmit(AjaxRequestTarget target) {
+			if (submitHandler != null) {
+				submitHandler.accept(target, this.getForm());
 			}
-		};
+		}
 	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java Thu Jan 19 14:54:34 2017
@@ -40,6 +40,7 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.web.common.AddFolderDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
+import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxEventBehavior;
@@ -76,10 +77,13 @@ public abstract class FileTreePanel exte
 	final AjaxSplitButton download = new AjaxSplitButton("download", new ArrayList<IMenuItem>());
 	private final Form<Void> form = new Form<Void>("form");
 	private final AddFolderDialog addFolder;
+	private final ConfirmableBorderDialog trashConfirm;
+	private ConfirmableAjaxBorder trashBorder;
 
-	public FileTreePanel(String id, AddFolderDialog addFolder, Long roomId) {
+	public FileTreePanel(String id, Long roomId, AddFolderDialog addFolder, ConfirmableBorderDialog trashConfirm) {
 		super(id);
 		this.addFolder = addFolder;
+		this.trashConfirm = trashConfirm;
 		OmTreeProvider tp = new OmTreeProvider(roomId);
 		select(tp.getRoot(), null, false, false);
 		form.add(tree = new FileItemTree("tree", this, tp));
@@ -159,14 +163,17 @@ public abstract class FileTreePanel exte
 				update(target);
 			}
 		}));
-		trashToolbar.add(new ConfirmableAjaxBorder("trash", getString("80"), getString("713")) {
+		trashToolbar.add(trashBorder = new ConfirmableAjaxBorder("trash", getString("80"), getString("713"), trashConfirm) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
+			protected boolean isClickable() {
+				return !selected.isEmpty();
+			}
+
+			@Override
 			protected void onEvent(AjaxRequestTarget target) {
-				if (!selected.isEmpty()) {
-					super.onEvent(target);
-				}
+				super.onEvent(target);
 			}
 
 			@Override
@@ -319,7 +326,7 @@ public abstract class FileTreePanel exte
 		}
 		updateSelected(target);
 		if (target != null) {
-			target.add(download.setVisible(lastSelected.getType() == Type.Presentation || lastSelected.getType() == Type.Image));
+			target.add(trashBorder, download.setVisible(lastSelected.getType() == Type.Presentation || lastSelected.getType() == Type.Image));
 		}
 	}
 

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java Thu Jan 19 14:54:34 2017
@@ -27,6 +27,7 @@ import org.apache.openmeetings.db.dao.re
 import org.apache.openmeetings.db.dto.record.RecordingContainerData;
 import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.web.common.AddFolderDialog;
+import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.common.tree.FileTreePanel;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.wicket.Component;
@@ -37,11 +38,11 @@ public class RoomFilePanel extends FileT
 	private static final long serialVersionUID = 1L;
 	private final RoomPanel room;
 
-	public RoomFilePanel(String id, AddFolderDialog addFolder, RoomPanel room) {
-		super(id, addFolder, room.getRoom().getId());
+	public RoomFilePanel(String id, RoomPanel room, AddFolderDialog addFolder, ConfirmableBorderDialog trashConfirm) {
+		super(id, room.getRoom().getId(), addFolder, trashConfirm);
 		this.room = room;
 	}
-	
+
 	@Override
 	public void updateSizes() {
 		FileExplorerItemDao dao = getBean(FileExplorerItemDao.class);
@@ -55,16 +56,16 @@ public class RoomFilePanel extends FileT
 		homeSize.setObject(getHumanSize(userSize));
 		publicSize.setObject(getHumanSize(roomSize));
 	}
-	
+
 	@Override
 	protected void update(AjaxRequestTarget target, FileItem f) {
 	}
-	
+
 	@Override
 	protected String getContainment() {
 		return "";
 	}
-	
+
 	@Override
 	protected Component getUpload(String id) {
 		Component u = super.getUpload(id);

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html Thu Jan 19 14:54:34 2017
@@ -36,6 +36,7 @@
 		<div class="file list" wicket:id="tree"></div>
 	</wicket:fragment>
 	<div wicket:id="addFolder"></div>
+	<form wicket:id="form"><div wicket:id="confirm-trash"></div></form>
 	<div wicket:id="upload"></div>
 	<div wicket:id="confirm-kick" />
 </wicket:panel>

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java Thu Jan 19 14:54:34 2017
@@ -37,6 +37,7 @@ import org.apache.openmeetings.web.app.C
 import org.apache.openmeetings.web.app.Client.Pod;
 import org.apache.openmeetings.web.common.AddFolderDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
+import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
@@ -79,8 +80,8 @@ public class RoomSidebar extends Panel {
 	private final TabbedPanel tabs;
 	private final ITab userTab;
 	private final ITab fileTab;
-	private final UploadDialog upload;
-	private final RoomFilePanel roomFiles;
+	private UploadDialog upload;
+	private RoomFilePanel roomFiles;
 	private final SelfIconsPanel selfRights;
 	private ConfirmableAjaxBorder confirmKick;
 	private boolean showFiles;
@@ -281,9 +282,8 @@ public class RoomSidebar extends Panel {
 				selectedIdx = index;
 			}
 		}).setOutputMarkupId(true));
-		roomFiles = new RoomFilePanel("tree", addFolder, room);
 		selfRights = new SelfIconsPanel("icons", room.getClient(), room, true);
-		add(addFolder, upload = new UploadDialog("upload", room, roomFiles));
+		add(addFolder);
 		add(toggleRight, toggleActivity, roomAction, avSettings);
 	}
 
@@ -298,6 +298,10 @@ public class RoomSidebar extends Panel {
 				room.kickUser(target, kickedClient);
 			}
 		});
+		final Form<?> form = new Form<>("form");
+		ConfirmableBorderDialog confirmTrash = new ConfirmableBorderDialog("confirm-trash", getString("80"), getString("713"), form);
+		roomFiles = new RoomFilePanel("tree", room, addFolder, confirmTrash);
+		add(form.add(confirmTrash), upload = new UploadDialog("upload", room, roomFiles));
 	}
 
 	private TabListModel newTabModel() {

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java Thu Jan 19 14:54:34 2017
@@ -48,7 +48,7 @@ public class RecordingsPanel extends Use
 
 	public RecordingsPanel(String id) {
 		super(id);
-		add(fileTree = new FileTreePanel("tree", addFolder, null) {
+		add(fileTree = new FileTreePanel("tree", null, addFolder, null) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
@@ -59,7 +59,7 @@ public class RecordingsPanel extends Use
 					publicSize.setObject(getHumanSize(sizeData.getPublicFileSize()));
 				}
 			}
-			
+
 			@Override
 			protected void update(AjaxRequestTarget target, FileItem f) {
 				video.update(target, (Recording)f);

Modified: openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java (original)
+++ openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/BaseConverter.java Thu Jan 19 14:54:34 2017
@@ -19,8 +19,8 @@
 package org.apache.openmeetings.core.converter;
 
 import static org.apache.openmeetings.core.data.record.listener.async.BaseStreamWriter.TIME_TO_WAIT_FOR_FRAME;
-import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_JPG;
 import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_FLV;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_JPG;
 import static org.apache.openmeetings.util.OmFileHelper.getRecordingMetaData;
 import static org.apache.openmeetings.util.OmFileHelper.getStreamsSubDir;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
@@ -66,7 +66,7 @@ public abstract class BaseConverter {
 		path += app;
 		return path;
 	}
-	
+
 	public String getPathToFFMPEG() {
 		return getPath("ffmpeg_path", "ffmpeg");
 	}
@@ -82,7 +82,7 @@ public abstract class BaseConverter {
 	protected boolean isUseOldStyleFfmpegMap() {
 		return "1".equals(configurationDao.getConfValue("use.old.style.ffmpeg.map.option", String.class, "0"));
 	}
-	
+
 	protected File getStreamFolder(Recording recording) {
 		return getStreamsSubDir(recording.getRoomId());
 	}
@@ -94,11 +94,11 @@ public abstract class BaseConverter {
 	protected double diffSeconds(Date from, Date to) {
 		return diffSeconds(diff(from, to));
 	}
-	
+
 	protected double diffSeconds(long val) {
 		return ((double)val) / 1000;
 	}
-	
+
 	protected String formatMillis(long millis) {
 		long hours = TimeUnit.MILLISECONDS.toHours(millis);
 		millis -= TimeUnit.HOURS.toMillis(hours);
@@ -112,33 +112,33 @@ public abstract class BaseConverter {
 	protected void updateDuration(Recording r) {
 		r.setDuration(formatMillis(diff(r.getRecordEnd(), r.getRecordStart())));
 	}
-	
+
 	protected void deleteFileIfExists(File f) {
 		if (f.exists()) {
 			f.delete();
 		}
 	}
-	
+
 	protected String[] mergeAudioToWaves(List<File> waveFiles, File wav) throws IOException {
 		List<String> argv = new ArrayList<String>();
-		
+
 		argv.add(getPathToSoX());
 		argv.add("-m");
 		for (File arg : waveFiles) {
 			argv.add(arg.getCanonicalPath());
 		}
 		argv.add(wav.getCanonicalPath());
-		
+
 		return argv.toArray(new String[0]);
 	}
-	
+
 	protected void stripAudioFirstPass(Recording recording, List<ConverterProcessResult> returnLog,
 			List<File> waveFiles, File streamFolder)
 	{
 		stripAudioFirstPass(recording, returnLog, waveFiles, streamFolder
 				, metaDataDao.getAudioMetaDataByRecording(recording.getId()));
 	}
-	
+
 	private String[] addSoxPad(List<ConverterProcessResult> returnLog, String job, double length, double position, File inFile, File outFile) throws IOException {
 		//FIXME need to check this
 		if (length < 0 || position < 0) {
@@ -153,12 +153,12 @@ public abstract class BaseConverter {
 		returnLog.add(ProcessHelper.executeScript(job, argv));
 		return argv;
 	}
-	
+
 	private static File getMetaFlvSer(RecordingMetaData metaData) {
 		File metaDir = getStreamsSubDir(metaData.getRecording().getRoomId());
 		return new File(metaDir, metaData.getStreamName() + ".flv.ser");
 	}
-	
+
 	public static void printMetaInfo(RecordingMetaData metaData, String prefix) {
 		if (log.isDebugEnabled()) {
 			log.debug(String.format("### %s:: recording id %s; stream with id %s; current status: %s ", prefix, metaData.getRecording().getId()
@@ -169,7 +169,7 @@ public abstract class BaseConverter {
 			log.debug(String.format("### %s:: Ser file [%s] exists ? %s; size: %s, lastModified: %s ", prefix, metaSer.getPath(), metaSer.exists(), metaSer.length(), metaSer.lastModified()));
 		}
 	}
-	
+
 	protected RecordingMetaData waitForTheStream(long metaId) throws InterruptedException {
 		RecordingMetaData metaData = metaDataDao.get(metaId);
 		if (metaData.getStreamStatus() != Status.STOPPED) {
@@ -178,9 +178,9 @@ public abstract class BaseConverter {
 			long maxTimestamp = 0;
 			while(true) {
 				log.trace("### Stream not yet written Thread Sleep - " + metaId);
-				
+
 				metaData = metaDataDao.get(metaId);
-				
+
 				if (metaData.getStreamStatus() == Status.STOPPED) {
 					printMetaInfo(metaData, "Stream now written");
 					log.debug("### Thread continue ... " );
@@ -217,13 +217,13 @@ public abstract class BaseConverter {
 				if (++counter % 1000 == 0) {
 					printMetaInfo(metaData, "Still waiting");
 				}
-				
+
 				Thread.sleep(100L);
 			}
 		}
 		return metaData;
 	}
-	
+
 	protected void stripAudioFirstPass(Recording recording,
 			List<ConverterProcessResult> returnLog,
 			List<File> waveFiles, File streamFolder,
@@ -232,7 +232,7 @@ public abstract class BaseConverter {
 			// Init variables
 			log.debug("### meta Data Number - " + metaDataList.size());
 			log.debug("###################################################");
-	
+
 			for (RecordingMetaData metaData : metaDataList) {
 				long metaId = metaData.getId();
 				log.debug("### processing metadata: " + metaId);
@@ -240,49 +240,48 @@ public abstract class BaseConverter {
 					log.debug("Stream has not been started, error in recording " + metaId);
 					continue;
 				}
-				
+
 				metaData = waitForTheStream(metaId);
-	
+
 				File inputFlvFile = new File(streamFolder, OmFileHelper.getName(metaData.getStreamName(), EXTENSION_FLV));
-	
+
 				File outputWav = new File(streamFolder, metaData.getStreamName() + "_WAVE.wav");
-	
+
 				metaData.setWavAudioData(outputWav.getName());
-	
-				
+
 				log.debug("FLV File Name: {} Length: {} ", inputFlvFile.getName(), inputFlvFile.length());
-	
+
 				if (inputFlvFile.exists()) {
 					String[] argv = new String[] {
 							getPathToFFMPEG(), "-y"
 							, "-i", inputFlvFile.getCanonicalPath()
 							, "-af", "aresample=32k:min_comp=0.001:min_hard_comp=0.100000"
 							, outputWav.getCanonicalPath()};
-	
+
 					returnLog.add(ProcessHelper.executeScript("stripAudioFromFLVs", argv));
 				}
-	
+
 				if (outputWav.exists() && outputWav.length() != 0) {
 					metaData.setAudioValid(true);
 					// Strip Wave to Full Length
 					File outputGapFullWav = outputWav;
-	
+
 					// Fix Start/End in Audio
 					List<RecordingMetaDelta> metaDeltas = metaDeltaDao.getByMetaId(metaId);
-	
+
 					int counter = 0;
-	
+
 					for (RecordingMetaDelta metaDelta : metaDeltas) {
 						File inputFile = outputGapFullWav;
-	
+
 						// Strip Wave to Full Length
 						String hashFileGapsFullName = metaData.getStreamName() + "_GAP_FULL_WAVE_" + counter + ".wav";
 						outputGapFullWav = new File(streamFolder, hashFileGapsFullName);
-	
+
 						metaDelta.setWaveOutPutName(hashFileGapsFullName);
-	
+
 						String[] argv_sox = null;
-	
+
 						if (metaDelta.getDeltaTime() != null) {
 							double gapSeconds = diffSeconds(metaDelta.getDeltaTime());
 							if (metaDelta.isStartPadding()) {
@@ -291,43 +290,43 @@ public abstract class BaseConverter {
 								argv_sox = addSoxPad(returnLog, "fillGap", 0, gapSeconds, inputFile, outputGapFullWav);
 							}
 						}
-	
+
 						if (argv_sox != null) {
 							log.debug("START fillGap ################# Delta-ID :: " + metaDelta.getId());
-	
+
 							metaDeltaDao.update(metaDelta);
 							counter++;
 						} else {
 							outputGapFullWav = inputFile;
 						}
 					}
-	
+
 					// Strip Wave to Full Length
 					String hashFileFullName = metaData.getStreamName() + "_FULL_WAVE.wav";
 					File outputFullWav = new File(streamFolder, hashFileFullName);
-	
+
 					// Calculate delta at beginning
 					double startPad = diffSeconds(metaData.getRecordStart(), recording.getRecordStart());
-	
+
 					// Calculate delta at ending
 					double endPad = diffSeconds(recording.getRecordEnd(), metaData.getRecordEnd());
-	
+
 					addSoxPad(returnLog, "addStartEndToAudio", startPad, endPad, outputGapFullWav, outputFullWav);
-	
+
 					// Fix for Audio Length - Invalid Audio Length in Recorded Files
 					// Audio must match 100% the Video
 					log.debug("############################################");
 					log.debug("Trim Audio to Full Length -- Start");
-	
+
 					if (!outputFullWav.exists()) {
 						throw new Exception("Audio File does not exist , could not extract the Audio correctly");
 					}
 					metaData.setFullWavAudioData(hashFileFullName);
-	
+
 					// Finally add it to the row!
 					waveFiles.add(outputFullWav);
 				}
-	
+
 				metaDataDao.update(metaData);
 			}
 		} catch (Exception err) {
@@ -341,7 +340,7 @@ public abstract class BaseConverter {
 
 	protected List<String> addMp4OutParams(Recording r, List<String> argv, String mp4path) throws IOException {
 		argv.addAll(Arrays.asList(
-				"-c:v", "libx264",
+				"-c:v", "h264", //
 				"-crf", "24",
 				"-pix_fmt", "yuv420p",
 				"-preset", "medium",
@@ -349,7 +348,7 @@ public abstract class BaseConverter {
 				"-c:a", "libfaac",
 				"-c:a", "libfdk_aac",
 				"-ar", "22050",
-				"-b:a", "32k", //FIXME add quality constants 
+				"-b:a", "32k", //FIXME add quality constants
 				"-s", getDimensions(r), //
 				mp4path
 				));

Modified: openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java (original)
+++ openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/converter/FlvExplorerConverter.java Thu Jan 19 14:54:34 2017
@@ -44,7 +44,7 @@ public class FlvExplorerConverter extend
 	// Spring loaded Beans
 	@Autowired
 	private FileExplorerItemDao fileDao;
-	
+
 	private static class FlvDimension {
 		public FlvDimension(int width, int height) {
 			this.width = width;
@@ -66,8 +66,13 @@ public class FlvExplorerConverter extend
 				res = ProcessHelper.executeScript("Info ID :: " + f.getId(), args);
 				res.setExitCode(0); //normal code is 1, ffmpeg requires output file
 			} else {
-				String[] args = new String[] { getPathToFFMPEG(), "-y", "-i", f.getFile(ext).getCanonicalPath(),
-						"-c:a", "aac", "-c:v", "h264", "-pix_fmt", "yuv420p", mp4.getCanonicalPath() };
+				String[] args = new String[] { getPathToFFMPEG(), "-y"
+						, "-i", f.getFile(ext).getCanonicalPath() //
+						, "-c:v", "h264" //
+						, "-c:a", "libfaac" //
+						, "-c:a", "libfdk_aac" //
+						, "-pix_fmt", "yuv420p" //
+						, mp4.getCanonicalPath() };
 				res = ProcessHelper.executeScript("uploadFLV ID :: " + f.getId(), args);
 
 			}
@@ -93,16 +98,16 @@ public class FlvExplorerConverter extend
 
 		return logs;
 	}
-	
+
 	private static FlvDimension getFlvDimension(String txt) throws Exception {
 		Matcher matcher = p.matcher(txt);
-		
+
 		while (matcher.find()) {
 			String foundResolution = txt.substring(matcher.start(), matcher.end());
 			String[] resultions = foundResolution.split("x");
 			return new FlvDimension(Integer.valueOf(resultions[0]).intValue(), Integer.valueOf(resultions[1]).intValue());
 		}
-		
+
 		return new FlvDimension(100, 100); // will return 100x100 for non-video to be able to play
 	}
 }

Modified: openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java (original)
+++ openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/StoredFile.java Thu Jan 19 14:54:34 2017
@@ -19,7 +19,7 @@
 package org.apache.openmeetings.util;
 
 import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_JPG;
-import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
+
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
@@ -45,7 +45,7 @@ public class StoredFile {
 
 	private static final Set<String> chartExtensions = new HashSet<>(Arrays.asList("xchart"));
 
-	private static final Set<String> asIsExtensions = new HashSet<>(Arrays.asList(EXTENSION_MP4, EXTENSION_JPG, "xchart"));
+	private static final Set<String> asIsExtensions = new HashSet<>(Arrays.asList(EXTENSION_JPG, "xchart")); //mp4 removed to get video size
 
 	private final String name;
 	private final String ext;
@@ -97,7 +97,7 @@ public class StoredFile {
 		String[] mime = type.split("/");
 		return mime[0];
 	}
-	
+
 	public boolean isImage() {
 		String mime = getMimeType(this);
 		return MIME_IMAGE.equals(mime);

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Thu Jan 19 14:54:34 2017
@@ -90,6 +90,8 @@ import org.apache.wicket.request.cycle.R
 import org.apache.wicket.request.mapper.info.PageComponentInfo;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.wicket.resource.DynamicJQueryResourceReference;
 import org.apache.wicket.util.collections.ConcurrentHashSet;
 import org.slf4j.Logger;
 import org.springframework.web.context.WebApplicationContext;
@@ -101,7 +103,7 @@ import org.wicketstuff.dashboard.web.Das
 public class Application extends AuthenticatedWebApplication implements IApplication {
 	private static final Logger log = getLogger(Application.class, webAppRootKey);
 	private static boolean isInstalled;
-	private static ConcurrentHashMap<String, Client> ONLINE_USERS = new ConcurrentHashMap<>(); 
+	private static ConcurrentHashMap<String, Client> ONLINE_USERS = new ConcurrentHashMap<>();
 	private static ConcurrentHashMap<String, Client> INVALID_SESSIONS = new ConcurrentHashMap<>();
 	private static ConcurrentHashMap<Long, Set<String>> ROOMS = new ConcurrentHashMap<>();
 	//additional maps for faster searching should be created
@@ -119,14 +121,15 @@ public class Application extends Authent
 		wicketApplicationName = super.getName();
 		getSecuritySettings().setAuthenticationStrategy(new OmAuthenticationStrategy());
 		getApplicationSettings().setAccessDeniedPage(AccessDeniedPage.class);
-		
-		//Add custom resource loader at the beginning, so it will be checked first in the 
-		//chain of Resource Loaders, if not found it will search in Wicket's internal 
+
+		//Add custom resource loader at the beginning, so it will be checked first in the
+		//chain of Resource Loaders, if not found it will search in Wicket's internal
 		//Resource Loader for a the property key
 		getResourceSettings().getStringResourceLoaders().add(0, new LabelResourceLoader());
-		
+		getJavaScriptLibrarySettings().setJQueryReference(new JavaScriptResourceReference(DynamicJQueryResourceReference.class, DynamicJQueryResourceReference.VERSION_2));
+
 		super.init();
-		
+
 		// register some widgets
 		dashboardContext = new DashboardContext();
 		dashboardContext.setDashboardPersister(new UserDashboardPersister());
@@ -141,7 +144,7 @@ public class Application extends Authent
 		DashboardSettings dashboardSettings = DashboardSettings.get();
 		dashboardSettings.setIncludeJQuery(false);
 		dashboardSettings.setIncludeJQueryUI(false);
-		
+
 		getRootRequestMapperAsCompound().add(new NoVersionMapper(getHomePage()));
 		getRootRequestMapperAsCompound().add(new NoVersionMapper("notinited", NotInitedPage.class));
 		getRootRequestMapperAsCompound().add(new NoVersionMapper(HASH_MAPPING, HashPage.class));
@@ -160,7 +163,7 @@ public class Application extends Authent
 		public NoVersionMapper(final Class<? extends IRequestablePage> pageClass) {
 			this("/", pageClass);
 		}
-		
+
 		public NoVersionMapper(String mountPath, final Class<? extends IRequestablePage> pageClass) {
 			super(mountPath, pageClass, new PageParametersEncoder());
 		}
@@ -169,7 +172,7 @@ public class Application extends Authent
 		protected void encodePageComponentInfo(Url url, PageComponentInfo info) {
 			//Does nothing
 		}
-		
+
 		@Override
 		public Url mapHandler(IRequestHandler requestHandler) {
 			if (requestHandler instanceof ListenerInterfaceRequestHandler || requestHandler instanceof BookmarkableListenerInterfaceRequestHandler) {
@@ -183,7 +186,7 @@ public class Application extends Authent
 	public static OmAuthenticationStrategy getAuthenticationStrategy() {
 		return (OmAuthenticationStrategy)get().getSecuritySettings().getAuthenticationStrategy();
 	}
-	
+
 	@Override
 	public Class<? extends Page> getHomePage() {
 		return MainPage.class;
@@ -198,27 +201,27 @@ public class Application extends Authent
 	public Class<? extends WebPage> getSignInPageClass() {
 		return SignInPage.class;
 	}
-	
+
 	public static Application get() {
 		return (Application) WebApplication.get();
 	}
-	
+
 	public static DashboardContext getDashboardContext() {
 		return get().dashboardContext;
 	}
-	
+
 	public static void addOnlineUser(Client c) {
 		log.debug("Adding online client: {}, room: {}", c.getUid(), c.getRoomId());
 		ONLINE_USERS.put(c.getUid(), c);
 	}
-	
+
 	public static void removeOnlineUser(Client c) {
 		if (c != null) {
 			log.debug("Removing online client: {}, room: {}", c.getUid(), c.getRoomId());
 			ONLINE_USERS.remove(c.getUid());
 		}
 	}
-	
+
 	@Override
 	public org.apache.openmeetings.db.entity.room.Client updateClient(org.apache.openmeetings.db.entity.room.Client rcl) {
 		if (rcl == null) {
@@ -259,11 +262,11 @@ public class Application extends Authent
 		}
 		return rcl;
 	}
-	
+
 	public static Client getOnlineClient(String uid) {
 		return uid == null ? null : ONLINE_USERS.get(uid);
 	}
-	
+
 	public static boolean isUserOnline(Long userId) {
 		boolean isUserOnline = false;
 		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
@@ -271,7 +274,7 @@ public class Application extends Authent
 				isUserOnline = true;
 				break;
 			}
-		} 
+		}
 		return isUserOnline;
 	}
 
@@ -289,11 +292,11 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static int getClientsSize() {
 		return ONLINE_USERS.size();
 	}
-	
+
 	public static Client getClientByKeys(Long userId, String sessionId) {
 		Client client = null;
 		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
@@ -302,10 +305,10 @@ public class Application extends Authent
 				client = c;
 				break;
 			}
-		} 
+		}
 		return client;
 	}
-	
+
 	@Override
 	public void invalidateClient(Long userId, String sessionId) {
 		Client client = getClientByKeys(userId, sessionId);
@@ -316,24 +319,24 @@ public class Application extends Authent
 			}
 		}
 	}
-	
+
 	public static boolean isInvaldSession(String sessionId) {
 		return sessionId == null ? false : INVALID_SESSIONS.containsKey(sessionId);
 	}
-	
+
 	public static void removeInvalidSession(String sessionId) {
 		if (sessionId != null){
 			INVALID_SESSIONS.remove(sessionId);
 		}
 	}
-	
+
 	public static Client addUserToRoom(Client c) {
 		log.debug("Adding online room client: {}, room: {}", c.getUid(), c.getRoomId());
 		ROOMS.putIfAbsent(c.getRoomId(), new ConcurrentHashSet<String>());
 		ROOMS.get(c.getRoomId()).add(c.getUid());
 		return c;
 	}
-	
+
 	public static Client removeUserFromRoom(Client c) {
 		log.debug("Removing online room client: {}, room: {}", c.getUid(), c.getRoomId());
 		if (c.getRoomId() != null) {
@@ -347,7 +350,7 @@ public class Application extends Authent
 		}
 		return c;
 	}
-	
+
 	public static List<Client> getRoomClients(Long roomId) {
 		List<Client> clients = new ArrayList<>();
 		if (roomId != null) {
@@ -363,7 +366,7 @@ public class Application extends Authent
 		}
 		return clients;
 	}
-	
+
 	public static Set<Long> getUserRooms(Long userId) {
 		Set<Long> result = new HashSet<>();
 		for (Entry<Long, Set<String>> me : ROOMS.entrySet()) {
@@ -376,7 +379,7 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static boolean isUserInRoom(long roomId, long userId) {
 		Set<String> clients = ROOMS.get(roomId);
 		if (clients != null) {
@@ -388,7 +391,7 @@ public class Application extends Authent
 		}
 		return false;
 	}
-	
+
 	//TODO need more safe way FIXME
 	public <T> T _getBean(Class<T> clazz) {
 		WebApplicationContext wac = getWebApplicationContext(getServletContext());
@@ -410,15 +413,15 @@ public class Application extends Authent
 		}
 		return loc;
 	}
-	
+
 	public static String getString(String key, final long languageId) {
 		return getString(key, getLocale(languageId));
 	}
-	
+
 	public static String getString(long id, final long languageId) {
 		return getString(id, getLocale(languageId));
 	}
-	
+
 	public static String getString(long id, final Locale loc) {
 		return getString("" + id, loc);
 	}
@@ -452,7 +455,7 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static <T> T getBean(Class<T> clazz) {
 		if (InitializationContainer.initComplete) {
 			if (!isInstalled()) {
@@ -463,7 +466,7 @@ public class Application extends Authent
 			throw new RestartResponseException(NotInitedPage.class);
 		}
 	}
-	
+
 	@Override
 	public <T> T getOmBean(Class<T> clazz) { //FIXME hack for email templates support (should be in separate module for now
 		return Application.getBean(clazz);
@@ -504,12 +507,12 @@ public class Application extends Authent
 		}
 		return link;
 	}
-	
+
 	@Override
 	public String getOmInvitationLink(Invitation i) { //FIXME hack for email templates support (should be in separate module for now
 		return getInvitationLink(i);
 	}
-	
+
 	public static String urlForPage(Class<? extends Page> clazz, PageParameters pp) {
 		RequestCycle rc = RequestCycle.get();
 		return rc.getUrlRenderer().renderFullUrl(Url.parse(getBean(ConfigurationDao.class).getBaseUrl() + rc.urlFor(clazz, pp)));
@@ -524,7 +527,7 @@ public class Application extends Authent
 	public String getOmString(long id) {
 		return getString(id);
 	}
-	
+
 	@Override
 	public String getOmString(long id, long languageId) {
 		return getString(id, languageId);

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ConfirmableAjaxBorder.java Thu Jan 19 14:54:34 2017
@@ -18,11 +18,15 @@
  */
 package org.apache.openmeetings.web.common;
 
+import java.io.Serializable;
+import java.util.function.BiConsumer;
+
 import org.apache.wicket.ajax.AjaxEventBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
 import org.apache.wicket.markup.html.border.Border;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.EmptyPanel;
 import org.apache.wicket.model.Model;
 
 import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
@@ -33,25 +37,40 @@ import com.googlecode.wicket.jquery.ui.w
 
 public abstract class ConfirmableAjaxBorder extends Border {
 	private static final long serialVersionUID = 1L;
+	private static final String DIALOG_ID = "dialog";
 	private final Form<?> form = new Form<>("form");
-	private final Form<?> userForm;
-	private final AbstractFormDialog<?> dialog;
+	private final ConfirmableBorderDialog dialog;
 
 	public ConfirmableAjaxBorder(String id, String title, String message) {
-		this(id, title, message, null);
+		this(id, title, message, null, null);
 	}
-	
+
 	public ConfirmableAjaxBorder(String id, String title, String message, Form<?> form) {
+		this(id, title, message, form, null);
+	}
+
+	public ConfirmableAjaxBorder(String id, String title, String message, ConfirmableBorderDialog dialog) {
+		this(id, title, message, null, dialog);
+	}
+
+	public ConfirmableAjaxBorder(String id, String title, String message, Form<?> userForm, ConfirmableBorderDialog dialog) {
 		super(id, Model.of(message));
-		dialog = newFormDialog("dialog", title, message);
-		this.userForm = form;
+		if (dialog == null) {
+			this.dialog = new ConfirmableBorderDialog(DIALOG_ID, title, message, userForm == null ? form : userForm);
+			form.add(this.dialog);
+		} else {
+			this.dialog = dialog;
+			form.add(new EmptyPanel(DIALOG_ID));
+		}
+		this.dialog.setSubmitHandler((BiConsumer<AjaxRequestTarget,Form<?>> & Serializable)(t, f)->onSubmit(t, f));
+		this.dialog.setErrorHandler((BiConsumer<AjaxRequestTarget,Form<?>> & Serializable)(t, f)->onError(t, f));
 		setOutputMarkupId(true);
 	}
 
 	public AbstractFormDialog<?> getDialog() {
 		return dialog;
 	}
-	
+
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();
@@ -63,27 +82,33 @@ public abstract class ConfirmableAjaxBor
 				super.updateAjaxAttributes(attributes);
 				ConfirmableAjaxBorder.this.updateAjaxAttributes(attributes);
 			}
-			
+
 			@Override
 			protected void onEvent(AjaxRequestTarget target) {
-				dialog.open(target);
+				if (isClickable()) {
+					dialog.open(target);
+				}
 			}
 		});
-		addToBorder(form.add(dialog));
+		addToBorder(form);
+	}
+
+	protected boolean isClickable() {
+		return true;
 	}
 
 	/**
 	 * Gives a chance to the specializations to modify the attributes.
-	 * 
+	 *
 	 * @param attributes attributes
 	 */
 	protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
 	}
-	
+
 	protected void onEvent(AjaxRequestTarget target) {
 		dialog.open(target);
 	}
-	
+
 	/**
 	 * Triggered when the form is submitted, but the validation failed
 	 *
@@ -101,39 +126,52 @@ public abstract class ConfirmableAjaxBor
 	 */
 	protected abstract void onSubmit(AjaxRequestTarget target, Form<?> form);
 
-	/**
-	 * Create the dialog instance<br/>
-	 * <b>Warning:</b> to be overridden with care!
-	 *
-	 * @param id the markupId
-	 * @param title the title of the dialog
-	 * @param message the message to be displayed
-	 * @return the dialog instance
-	 */
-	protected AbstractFormDialog<?> newFormDialog(String id, String title, String message) {
-		return new MessageFormDialog(id, title, message, DialogButtons.OK_CANCEL, DialogIcon.WARN) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public DialogButton getSubmitButton() {
-				return this.findButton(OK);
-			}
-
-			@Override
-			public Form<?> getForm() {
-				return userForm == null ? form : userForm;
-			}
-
-			@Override
-			protected void onError(AjaxRequestTarget target) {
-				super.close(target, null); // closes the dialog on error.
-				ConfirmableAjaxBorder.this.onError(target, this.getForm());
-			}
-
-			@Override
-			protected void onSubmit(AjaxRequestTarget target) {
-				ConfirmableAjaxBorder.this.onSubmit(target, this.getForm());
+	public static class ConfirmableBorderDialog extends MessageFormDialog {
+		private static final long serialVersionUID = 1L;
+		private Form<?> form;
+		private BiConsumer<AjaxRequestTarget,Form<?>> submitHandler = null;
+		private BiConsumer<AjaxRequestTarget,Form<?>> errorHandler = null;
+
+		public ConfirmableBorderDialog(String id, String title, String message) {
+			this(id, title, message, null);
+		}
+
+		public ConfirmableBorderDialog(String id, String title, String message, Form<?> form) {
+			super(id, title, message, DialogButtons.OK_CANCEL, DialogIcon.WARN);
+			this.form = form;
+		}
+
+		public void setSubmitHandler(BiConsumer<AjaxRequestTarget, Form<?>> submitHandler) {
+			this.submitHandler = submitHandler;
+		}
+
+		public void setErrorHandler(BiConsumer<AjaxRequestTarget, Form<?>> errorHandler) {
+			this.errorHandler = errorHandler;
+		}
+
+		@Override
+		public DialogButton getSubmitButton() {
+			return this.findButton(OK);
+		}
+
+		@Override
+		public Form<?> getForm() {
+			return this.form;
+		}
+
+		@Override
+		protected void onError(AjaxRequestTarget target) {
+			super.close(target, null); // closes the dialog on error.
+			if (errorHandler != null) {
+				errorHandler.accept(target, this.getForm());
+			}
+		}
+
+		@Override
+		protected void onSubmit(AjaxRequestTarget target) {
+			if (submitHandler != null) {
+				submitHandler.accept(target, this.getForm());
 			}
-		};
+		}
 	}
 }

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java Thu Jan 19 14:54:34 2017
@@ -18,10 +18,12 @@
  */
 package org.apache.openmeetings.web.common;
 
-import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.openmeetings.db.util.AuthLevelUtil.hasAdminLevel;
+import static org.apache.openmeetings.db.util.AuthLevelUtil.hasGroupAdminLevel;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.LEVEL_ADMIN;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.LEVEL_GROUP_ADMIN;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.LEVEL_USER;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.addOnlineUser;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.removeOnlineUser;
@@ -33,8 +35,6 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.OmUrlFragment.PROFILE_MESSAGES;
 import static org.apache.openmeetings.web.util.OmUrlFragment.getPanel;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
-import static org.apache.openmeetings.db.util.AuthLevelUtil.hasAdminLevel;
-import static org.apache.openmeetings.db.util.AuthLevelUtil.hasGroupAdminLevel;
 
 import java.io.IOException;
 import java.util.ArrayList;

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/tree/FileTreePanel.java Thu Jan 19 14:54:34 2017
@@ -40,6 +40,7 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.web.common.AddFolderDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
+import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.util.AjaxDownload;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxEventBehavior;
@@ -76,10 +77,13 @@ public abstract class FileTreePanel exte
 	final AjaxSplitButton download = new AjaxSplitButton("download", new ArrayList<IMenuItem>());
 	private final Form<Void> form = new Form<Void>("form");
 	private final AddFolderDialog addFolder;
+	private final ConfirmableBorderDialog trashConfirm;
+	private ConfirmableAjaxBorder trashBorder;
 
-	public FileTreePanel(String id, AddFolderDialog addFolder, Long roomId) {
+	public FileTreePanel(String id, Long roomId, AddFolderDialog addFolder, ConfirmableBorderDialog trashConfirm) {
 		super(id);
 		this.addFolder = addFolder;
+		this.trashConfirm = trashConfirm;
 		OmTreeProvider tp = new OmTreeProvider(roomId);
 		select(tp.getRoot(), null, false, false);
 		form.add(tree = new FileItemTree("tree", this, tp));
@@ -159,14 +163,17 @@ public abstract class FileTreePanel exte
 				update(target);
 			}
 		}));
-		trashToolbar.add(new ConfirmableAjaxBorder("trash", getString("80"), getString("713")) {
+		trashToolbar.add(trashBorder = new ConfirmableAjaxBorder("trash", getString("80"), getString("713"), trashConfirm) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
+			protected boolean isClickable() {
+				return !selected.isEmpty();
+			}
+
+			@Override
 			protected void onEvent(AjaxRequestTarget target) {
-				if (!selected.isEmpty()) {
-					super.onEvent(target);
-				}
+				super.onEvent(target);
 			}
 
 			@Override
@@ -319,7 +326,7 @@ public abstract class FileTreePanel exte
 		}
 		updateSelected(target);
 		if (target != null) {
-			target.add(download.setVisible(lastSelected.getType() == Type.Presentation || lastSelected.getType() == Type.Image));
+			target.add(trashBorder, download.setVisible(lastSelected.getType() == Type.Presentation || lastSelected.getType() == Type.Image));
 		}
 	}
 

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomFilePanel.java Thu Jan 19 14:54:34 2017
@@ -27,6 +27,7 @@ import org.apache.openmeetings.db.dao.re
 import org.apache.openmeetings.db.dto.record.RecordingContainerData;
 import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.web.common.AddFolderDialog;
+import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.common.tree.FileTreePanel;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.wicket.Component;
@@ -37,11 +38,11 @@ public class RoomFilePanel extends FileT
 	private static final long serialVersionUID = 1L;
 	private final RoomPanel room;
 
-	public RoomFilePanel(String id, AddFolderDialog addFolder, RoomPanel room) {
-		super(id, addFolder, room.getRoom().getId());
+	public RoomFilePanel(String id, RoomPanel room, AddFolderDialog addFolder, ConfirmableBorderDialog trashConfirm) {
+		super(id, room.getRoom().getId(), addFolder, trashConfirm);
 		this.room = room;
 	}
-	
+
 	@Override
 	public void updateSizes() {
 		FileExplorerItemDao dao = getBean(FileExplorerItemDao.class);
@@ -55,16 +56,16 @@ public class RoomFilePanel extends FileT
 		homeSize.setObject(getHumanSize(userSize));
 		publicSize.setObject(getHumanSize(roomSize));
 	}
-	
+
 	@Override
 	protected void update(AjaxRequestTarget target, FileItem f) {
 	}
-	
+
 	@Override
 	protected String getContainment() {
 		return "";
 	}
-	
+
 	@Override
 	protected Component getUpload(String id) {
 		Component u = super.getUpload(id);

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.html Thu Jan 19 14:54:34 2017
@@ -36,6 +36,7 @@
 		<div class="file list" wicket:id="tree"></div>
 	</wicket:fragment>
 	<div wicket:id="addFolder"></div>
+	<form wicket:id="form"><div wicket:id="confirm-trash"></div></form>
 	<div wicket:id="upload"></div>
 	<div wicket:id="confirm-kick" />
 </wicket:panel>

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java Thu Jan 19 14:54:34 2017
@@ -37,6 +37,7 @@ import org.apache.openmeetings.web.app.C
 import org.apache.openmeetings.web.app.Client.Pod;
 import org.apache.openmeetings.web.common.AddFolderDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
+import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
@@ -79,8 +80,8 @@ public class RoomSidebar extends Panel {
 	private final TabbedPanel tabs;
 	private final ITab userTab;
 	private final ITab fileTab;
-	private final UploadDialog upload;
-	private final RoomFilePanel roomFiles;
+	private UploadDialog upload;
+	private RoomFilePanel roomFiles;
 	private final SelfIconsPanel selfRights;
 	private ConfirmableAjaxBorder confirmKick;
 	private boolean showFiles;
@@ -281,9 +282,8 @@ public class RoomSidebar extends Panel {
 				selectedIdx = index;
 			}
 		}).setOutputMarkupId(true));
-		roomFiles = new RoomFilePanel("tree", addFolder, room);
 		selfRights = new SelfIconsPanel("icons", room.getClient(), room, true);
-		add(addFolder, upload = new UploadDialog("upload", room, roomFiles));
+		add(addFolder);
 		add(toggleRight, toggleActivity, roomAction, avSettings);
 	}
 
@@ -298,6 +298,10 @@ public class RoomSidebar extends Panel {
 				room.kickUser(target, kickedClient);
 			}
 		});
+		final Form<?> form = new Form<>("form");
+		ConfirmableBorderDialog confirmTrash = new ConfirmableBorderDialog("confirm-trash", getString("80"), getString("713"), form);
+		roomFiles = new RoomFilePanel("tree", room, addFolder, confirmTrash);
+		add(form.add(confirmTrash), upload = new UploadDialog("upload", room, roomFiles));
 	}
 
 	private TabListModel newTabModel() {

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java?rev=1779474&r1=1779473&r2=1779474&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingsPanel.java Thu Jan 19 14:54:34 2017
@@ -48,7 +48,7 @@ public class RecordingsPanel extends Use
 
 	public RecordingsPanel(String id) {
 		super(id);
-		add(fileTree = new FileTreePanel("tree", addFolder, null) {
+		add(fileTree = new FileTreePanel("tree", null, addFolder, null) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
@@ -59,7 +59,7 @@ public class RecordingsPanel extends Use
 					publicSize.setObject(getHumanSize(sizeData.getPublicFileSize()));
 				}
 			}
-			
+
 			@Override
 			protected void update(AjaxRequestTarget target, FileItem f) {
 				video.update(target, (Recording)f);