--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<project name="gss" default="package-war" basedir=".">
+ <description>The GSS project build file</description>
+
+ <property file="build.properties"/>
+ <property name="deps.dir" value="dependencies"/>
+
+ <property name="gwt.workers" value="1"/>
+ <property name="jboss.args" value="-b 0.0.0.0" />
+
+ <property name="jboss.version" value="5.1.0"/>
+ <property name="jboss.home" value="${deps.dir}/jboss-${jboss.version}.GA" />
+ <property name="jboss.bin.dir" value="${jboss.home}/bin" />
+ <property name="jboss.conf.dir" value="${jboss.home}/server/default/conf" />
+ <property name="jboss.deploy.dir" value="${jboss.home}/server/default/deploy" />
+ <property name="jboss.lib.dir" value="${jboss.home}/server/default/lib" />
+ <property name="jboss.root.lib.dir" value="${jboss.home}/lib" />
+ <property name="jboss.common.lib.dir" value="${jboss.home}/common/lib" />
+ <property name="jboss.filename" value="jboss-${jboss.version}.GA-jdk6.zip"/>
+ <property name="jboss.download.url" value="http://switch.dl.sourceforge.net/project/jboss/JBoss/JBoss-${jboss.version}.GA/${jboss.filename}"/>
+
+ <property name="gwt.version" value="2.1.1"/>
+ <property name="gwt.home" value="${deps.dir}/gwt-${gwt.version}"/>
+ <property name="gwt.filename" value="gwt-${gwt.version}.zip"/>
+ <property name="gwt.download.url" value="http://google-web-toolkit.googlecode.com/files/${gwt.filename}"/>
+
+ <property name="gwt-gears.version" value="1.3.0"/>
+ <property name="gwt-gears.home" value="${deps.dir}/gwt-gears-${gwt-gears.version}" />
+ <property name="gwt-gears.filename" value="gwt-gears-${gwt-gears.version}.zip"/>
+ <property name="gwt-gears.download.url" value="http://gwt-google-apis.googlecode.com/files/${gwt-gears.filename}"/>
+
+ <property name="gwt-incubator.filename" value="gwt-incubator-20101117-r1766.jar"/>
+ <property name="gwt-incubator.download.url" value="http://google-web-toolkit-incubator.googlecode.com/files/gwt-incubator-20101117-r1766.jar"/>
+ <property name="gwt-visualization.home" value="${deps.dir}/gwt-visualization-1.1.0" />
+ <property name="gwt-visualization.filename" value="gwt-visualization-1.1.0.zip"/>
+ <property name="gwt-visualization.download.url" value="http://gwt-google-apis.googlecode.com/files/${gwt-visualization.filename}"/>
+
+ <property name="gwtquery.filename" value="gwtquery-1.0.0-20110116.074055-7.jar"/>
+ <property name="gwtquery.download.url" value="http://gss.googlecode.com/hg/lib/${gwtquery.filename}?r=0473a2c1bc32c9426423f8ca3b688a29ce30216b"/>
+ <property name="gwtquery-draggable-plugin.filename" value="draggable-plugin-1.0.2.jar"/>
+ <property name="gwtquery-draggable-plugin.download.url" value="http://gss.googlecode.com/hg/lib/${gwtquery-draggable-plugin.filename}?r=0634eeeeaaad1b9bfb7a8e809bfc9e9545d208e2"/>
+ <property name="gwtquery-droppable-plugin.filename" value="droppable-plugin-1.0.2.jar"/>
+ <property name="gwtquery-droppable-plugin.download.url" value="http://gss.googlecode.com/hg/lib/${gwtquery-droppable-plugin.filename}?r=c8bca56a1c4ab780ac0d0cc72a2b40b60d7ca4f7"/>
+ <property name="gwtquery-commonui-plugin.filename" value="commonui-plugin-1.0.3.jar"/>
+ <property name="gwtquery-commonui-plugin.download.url" value="http://gss.googlecode.com/hg/lib/${gwtquery-commonui-plugin.filename}?r=0473a2c1bc32c9426423f8ca3b688a29ce30216b"/>
+
+ <property name="root.context" value="gss" />
+ <property name="gwt.module.class" value="GSS" />
+ <property name="gwt.root.package" value="org.gss_project.gss.web" />
+ <property name="gwt.root.path" value="org/gss_project/gss/web" />
+ <property name="gwt.module" value="${gwt.root.package}.${gwt.module.class}" />
+
+ <property name="src.dir" value="${basedir}/src"/>
+
+ <!-- Build dirs -->
+ <property name="build.dir" value="${basedir}/bin" />
+ <property name="build.classes.dir" value="${build.dir}/classes" />
+ <property name="gwt.www.dir" value="${build.dir}/www" />
+ <property name="gwt.www.admin.dir" value="${build.dir}/wwwadmin" />
+ <property name="dist.war" value="${ant.project.name}.war"/>
+ <property name="war.dir" value="${basedir}/war" />
+ <property name="war.web-inf.dir" value="${war.dir}/WEB-INF"/>
+ <property name="war.lib.dir" value="${war.web-inf.dir}/lib"/>
+
+ <!-- set classpath -->
+ <path id="project.class.path">
+ <pathelement location="${gwt.home}/gwt-user.jar"/>
+ <pathelement location="${war.lib.dir}/commons-fileupload-1.2.jar"/>
+ </path>
+
+ <target name="check-dependencies" description="Checks if all dependencies are present">
+ <condition property="dependencies.present">
+ <and>
+ <available file="${jboss.home}" type="dir"/>
+ <available file="${gwt.home}" type="dir"/>
+ <available file="${gwt-gears.home}" type="dir"/>
+ <available file="${deps.dir}/${gwtquery.filename}"/>
+ <available file="${deps.dir}/${gwtquery-draggable-plugin.filename}"/>
+ <available file="${deps.dir}/${gwtquery-droppable-plugin.filename}"/>
+ <available file="${deps.dir}/${gwtquery-commonui-plugin.filename}"/>
+ <available file="${deps.dir}/${gwt-incubator.filename}"/>
+ <available file="${deps.dir}/${gwt-visualization.filename}"/>
+ </and>
+ </condition>
+ <echo message="dependencies.present=${dependencies.present}"/>
+ </target>
+
+ <target name="fetch-dependencies" unless="dependencies.present" description="Fetch the dpendencies if not present" depends="check-dependencies">
+ <mkdir dir="${deps.dir}"/>
+ <get src="${gwt.download.url}" dest="${deps.dir}/${gwt.filename}" usetimestamp="true"/>
+ <get src="${gwt-gears.download.url}" dest="${deps.dir}/${gwt-gears.filename}" usetimestamp="true"/>
+ <get src="${gwt-incubator.download.url}" dest="${deps.dir}/${gwt-incubator.filename}"/>
+ <get src="${gwt-visualization.download.url}" dest="${deps.dir}/${gwt-visualization.filename}"/>
+ <get src="${gwtquery.download.url}" dest="${deps.dir}/${gwtquery.filename}" usetimestamp="true"/>
+ <get src="${gwtquery-draggable-plugin.download.url}" dest="${deps.dir}/${gwtquery-draggable-plugin.filename}" usetimestamp="true"/>
+ <get src="${gwtquery-droppable-plugin.download.url}" dest="${deps.dir}/${gwtquery-droppable-plugin.filename}" usetimestamp="true"/>
+ <get src="${gwtquery-commonui-plugin.download.url}" dest="${deps.dir}/${gwtquery-commonui-plugin.filename}" usetimestamp="true"/>
+ <unzip src="${deps.dir}/${gwt.filename}" dest="${gwt.home}/.."/>
+ <unzip src="${deps.dir}/${gwt-gears.filename}" dest="${gwt-gears.home}/.."/>
+ <unzip src="${deps.dir}/${gwt-visualization.filename}" dest="${gwt-visualization.home}/.."/>
+ </target>
+
+ <target name="check-gwt-compile" description="Checks is the web gwt client sources are up-to-date with the compiled artifacts">
+ <uptodate property="compilation-not-needed">
+ <srcfiles dir="${src.dir}">
+ <include name="${gwt.root.path}/**"/>
+ </srcfiles>
+ <mergemapper to="${gwt.www.dir}/${gwt.module}/${gwt.module}.nocache.js"/>
+ </uptodate>
+ </target>
+
+ <target name="gwt-compile" depends="check-gwt-compile, fetch-dependencies" unless="compilation-not-needed" description="Compile the gwt web client code to JavaScript">
+ <java classname="com.google.gwt.dev.Compiler" failonerror="true" fork="true">
+ <arg value="-localWorkers" />
+ <arg value="${gwt.workers}" />
+ <arg value="-war"/>
+ <arg value="${gwt.www.dir}"/>
+ <arg value="${gwt.module}"/>
+
+ <classpath>
+ <pathelement path="${gwt.home}/gwt-dev.jar"/>
+ <pathelement location="${deps.dir}/${gwtquery.filename}"/>
+ <pathelement location="${deps.dir}/${gwtquery-droppable-plugin.filename}"/>
+ <pathelement location="${deps.dir}/${gwtquery-draggable-plugin.filename}"/>
+ <pathelement location="${deps.dir}/${gwtquery-commonui-plugin.filename}"/>
+ <pathelement location="${gwt-gears.home}/gwt-gears.jar"/>
+ <pathelement path="${gwt.home}/gwt-user.jar" />
+ <path refid="project.class.path"/>
+ <pathelement path="${src.dir}" />
+ </classpath>
+ </java>
+ <!--move file="${gwt.www.dir}/${gwt.module}/${gwt.module.class}.html" tofile="${gwt.www.dir}/${gwt.module}/index.html"/-->
+ </target>
+
+ <target name="package-war" depends="gwt-compile" description="Package up the web client as a war">
+ <jar destfile="${build.dir}/${dist.war}">
+ <zipfileset dir="${war.dir}"/>
+ <zipfileset dir="${gwt.www.dir}/${gwt.module}"/>
+ </jar>
+ </target>
+
+ <target name="clean" description="Delete all build artifacts">
+ <delete dir="${build.dir}"/>
+ </target>
+
+ <target name="distclean" depends="clean" description="Delete all downloaded dependencies">
+ <delete dir="${deps.dir}"/>
+ </target>
+
+ <target name="run-web-dev-mode" description="Run web client in development mode">
+ <java fork="true" classname="com.google.gwt.dev.DevMode" spawn="true">
+ <classpath>
+ <pathelement location="${src.dir}"/>
+ <pathelement location="${build.classes.dir}"/>
+ <pathelement path="${gwt.home}/gwt-dev.jar"/>
+ <pathelement location="${deps.dir}/${gwtquery.filename}"/>
+ <pathelement location="${deps.dir}/${gwtquery-draggable-plugin.filename}"/>
+ <pathelement location="${deps.dir}/${gwtquery-droppable-plugin.filename}"/>
+ <pathelement location="${deps.dir}/${gwtquery-commonui-plugin.filename}"/>
+ <pathelement location="${gwt-gears.home}/gwt-gears.jar"/>
+ <pathelement path="${gwt.home}/gwt-user.jar" />
+ <path refid="project.class.path"/>
+ </classpath>
+ <jvmarg value="-Xmx256M"/>
+ <jvmarg value="-Xdebug"/>
+ <jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=55555"/>
+ <arg value="-war"/>
+ <arg value="${gwt.www.dir}/${gwt.module}"/>
+ <arg value="-startupUrl"/>
+ <arg value="GSS.html"/>
+ <arg value="${gwt.module}"/>
+ </java>
+ </target>
+</project>
--- /dev/null
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.cellview.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.CssResource;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.resources.client.ImageResource.ImageOptions;
+import com.google.gwt.uibinder.client.UiConstructor;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Image;
+import com.google.gwt.view.client.HasRows;
+import com.google.gwt.view.client.Range;
+
+/**
+ * A pager for controlling a {@link HasRows} that only supports simple page
+ * navigation.
+ *
+ * <p>
+ * <h3>Example</h3>
+ * {@example com.google.gwt.examples.cellview.SimplePagerExample}
+ * </p>
+ */
+public class GssSimplePager extends AbstractPager {
+
+ /**
+ * A ClientBundle that provides images for this widget.
+ */
+ public static interface Resources extends ClientBundle {
+
+ /**
+ * The image used to skip ahead multiple pages.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerFastForward();
+
+ /**
+ * The disabled "fast forward" image.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerFastForwardDisabled();
+
+ /**
+ * The image used to go to the first page.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerFirstPage();
+
+ /**
+ * The disabled first page image.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerFirstPageDisabled();
+
+ /**
+ * The image used to go to the last page.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerLastPage();
+
+ /**
+ * The disabled last page image.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerLastPageDisabled();
+
+ /**
+ * The image used to go to the next page.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerNextPage();
+
+ /**
+ * The disabled next page image.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerNextPageDisabled();
+
+ /**
+ * The image used to go to the previous page.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerPreviousPage();
+
+ /**
+ * The disabled previous page image.
+ */
+ @ImageOptions(flipRtl = true)
+ ImageResource simplePagerPreviousPageDisabled();
+
+ /**
+ * The styles used in this widget.
+ */
+ @Source("SimplePager.css")
+ Style simplePagerStyle();
+ }
+
+ /**
+ * Styles used by this widget.
+ */
+ public static interface Style extends CssResource {
+
+ /**
+ * Applied to buttons.
+ */
+ String button();
+
+ /**
+ * Applied to disabled buttons.
+ */
+ String disabledButton();
+
+ /**
+ * Applied to the details text.
+ */
+ String pageDetails();
+ }
+
+ /**
+ * The location of the text relative to the paging buttons.
+ */
+ public static enum TextLocation {
+ CENTER, LEFT, RIGHT;
+ }
+
+ private static int DEFAULT_FAST_FORWARD_ROWS = 1000;
+ private static Resources DEFAULT_RESOURCES;
+
+ private static Resources getDefaultResources() {
+ if (DEFAULT_RESOURCES == null) {
+ DEFAULT_RESOURCES = GWT.create(Resources.class);
+ }
+ return DEFAULT_RESOURCES;
+ }
+
+ private final Image fastForward;
+
+ private final int fastForwardRows;
+
+ private final Image firstPage;
+
+ /**
+ * We use an {@link HTML} so we can embed the loading image.
+ */
+ private final HTML label = new HTML();
+
+ private final Image lastPage;
+
+ /**
+ * Set to true when the next and last buttons are disabled.
+ */
+ private boolean nextDisabled;
+
+ private final Image nextPage;
+
+ /**
+ * Set to true when the prev and first buttons are disabled.
+ */
+ private boolean prevDisabled;
+
+ private final Image prevPage;
+
+ /**
+ * The {@link Resources} used by this widget.
+ */
+ private final Resources resources;
+
+ /**
+ * The {@link Style} used by this widget.
+ */
+ private final Style style;
+
+ /**
+ * Construct a {@link GssSimplePager} with the default text location.
+ */
+ public GssSimplePager() {
+ this(TextLocation.CENTER);
+ }
+
+ /**
+ * Construct a {@link GssSimplePager} with the specified text location.
+ *
+ * @param location the location of the text relative to the buttons
+ */
+ @UiConstructor
+ // Hack for Google I/O demo
+ public GssSimplePager(TextLocation location) {
+ this(location, getDefaultResources(), false, DEFAULT_FAST_FORWARD_ROWS,
+ true);
+ }
+
+ /**
+ * Construct a {@link GssSimplePager} with the specified resources.
+ *
+ * @param location the location of the text relative to the buttons
+ * @param resources the {@link Resources} to use
+ * @param showFastForwardButton if true, show a fast-forward button that
+ * advances by a larger increment than a single page
+ * @param fastForwardRows the number of rows to jump when fast forwarding
+ * @param showLastPageButton if true, show a button to go the the last page
+ */
+ public GssSimplePager(TextLocation location, Resources resources,
+ boolean showFastForwardButton, final int fastForwardRows,
+ boolean showLastPageButton) {
+ this.resources = resources;
+ this.fastForwardRows = fastForwardRows;
+ this.style = resources.simplePagerStyle();
+ this.style.ensureInjected();
+
+ // Create the buttons.
+ firstPage = new Image(resources.simplePagerFirstPage());
+ firstPage.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ firstPage();
+ }
+ });
+ nextPage = new Image(resources.simplePagerNextPage());
+ nextPage.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ nextPage();
+ }
+ });
+ prevPage = new Image(resources.simplePagerPreviousPage());
+ prevPage.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ previousPage();
+ }
+ });
+ if (showLastPageButton) {
+ lastPage = new Image(resources.simplePagerLastPage());
+ lastPage.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ lastPage();
+ }
+ });
+ } else {
+ lastPage = null;
+ }
+ if (showFastForwardButton) {
+ fastForward = new Image(resources.simplePagerFastForward());
+ fastForward.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ setPage(getPage() + getFastForwardPages());
+ }
+ });
+ } else {
+ fastForward = null;
+ }
+
+ // Construct the widget.
+ HorizontalPanel layout = new HorizontalPanel();
+ layout.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
+ initWidget(layout);
+ if (location == TextLocation.RIGHT) {
+ layout.add(label);
+ }
+ layout.add(firstPage);
+ layout.add(prevPage);
+ if (location == TextLocation.CENTER) {
+ layout.add(label);
+ }
+ layout.add(nextPage);
+ if (showFastForwardButton) {
+ layout.add(fastForward);
+ }
+ if (showLastPageButton) {
+ layout.add(lastPage);
+ }
+ if (location == TextLocation.LEFT) {
+ layout.add(label);
+ }
+
+ // Add style names to the cells.
+ firstPage.getElement().getParentElement().addClassName(style.button());
+ prevPage.getElement().getParentElement().addClassName(style.button());
+ label.getElement().getParentElement().addClassName(style.pageDetails());
+ nextPage.getElement().getParentElement().addClassName(style.button());
+ if (showFastForwardButton) {
+ fastForward.getElement().getParentElement().addClassName(style.button());
+ }
+ if (showLastPageButton) {
+ lastPage.getElement().getParentElement().addClassName(style.button());
+ }
+
+ // Disable the buttons by default.
+ setDisplay(null);
+ }
+
+ @Override
+ public void firstPage() {
+ super.firstPage();
+ }
+
+ @Override
+ public int getPage() {
+ return super.getPage();
+ }
+
+ @Override
+ public int getPageCount() {
+ return super.getPageCount();
+ }
+
+ @Override
+ public boolean hasNextPage() {
+ return super.hasNextPage();
+ }
+
+ @Override
+ public boolean hasNextPages(int pages) {
+ return super.hasNextPages(pages);
+ }
+
+ @Override
+ public boolean hasPage(int index) {
+ return super.hasPage(index);
+ }
+
+ @Override
+ public boolean hasPreviousPage() {
+ return super.hasPreviousPage();
+ }
+
+ @Override
+ public boolean hasPreviousPages(int pages) {
+ return super.hasPreviousPages(pages);
+ }
+
+ @Override
+ public void lastPage() {
+ super.lastPage();
+ }
+
+ @Override
+ public void lastPageStart() {
+ super.lastPageStart();
+ }
+
+ @Override
+ public void nextPage() {
+ super.nextPage();
+ }
+
+ @Override
+ public void previousPage() {
+ super.previousPage();
+ }
+
+ @Override
+ public void setDisplay(HasRows display) {
+ // Enable or disable all buttons.
+ boolean disableButtons = (display == null);
+ setFastForwardDisabled(disableButtons);
+ setNextPageButtonsDisabled(disableButtons);
+ setPrevPageButtonsDisabled(disableButtons);
+ super.setDisplay(display);
+ }
+
+ @Override
+ public void setPage(int index) {
+ super.setPage(index);
+ }
+
+ @Override
+ public void setPageSize(int pageSize) {
+ super.setPageSize(pageSize);
+ }
+
+ @Override
+ public void setPageStart(int index) {
+ super.setPageStart(index);
+ }
+
+ /**
+ * Let the page know that the table is loading. Call this method to clear all
+ * data from the table and hide the current range when new data is being
+ * loaded into the table.
+ */
+ public void startLoading() {
+ getDisplay().setRowCount(0, true);
+ label.setHTML("");
+ }
+
+ /**
+ * Get the text to display in the pager that reflects the state of the pager.
+ *
+ * @return the text
+ */
+ protected String createText() {
+ // Default text is 1 based.
+ NumberFormat formatter = NumberFormat.getFormat("#,###");
+ HasRows display = getDisplay();
+ Range range = display.getVisibleRange();
+ int pageStart = range.getStart() + 1;
+ int pageSize = range.getLength();
+ int dataSize = display.getRowCount();
+ int endIndex = Math.min(dataSize, pageStart + pageSize - 1);
+ endIndex = Math.max(pageStart, endIndex);
+ boolean exact = display.isRowCountExact();
+ return formatter.format(pageStart) + "-" + formatter.format(endIndex)
+ + (exact ? " of " : " of over ") + formatter.format(dataSize);
+ }
+
+ @Override
+ protected void onRangeOrRowCountChanged() {
+ HasRows display = getDisplay();
+ label.setText(createText());
+
+ // Update the prev and first buttons.
+ setPrevPageButtonsDisabled(!hasPreviousPage());
+
+ // Update the next and last buttons.
+ if (isRangeLimited() || !display.isRowCountExact()) {
+ setNextPageButtonsDisabled(!hasNextPage());
+ setFastForwardDisabled(!hasNextPages(getFastForwardPages()));
+ }
+ }
+
+ /**
+ * Check if the next button is disabled. Visible for testing.
+ */
+ boolean isNextButtonDisabled() {
+ return nextDisabled;
+ }
+
+ /**
+ * Check if the previous button is disabled. Visible for testing.
+ */
+ boolean isPreviousButtonDisabled() {
+ return prevDisabled;
+ }
+
+ /**
+ * Get the number of pages to fast forward based on the current page size.
+ *
+ * @return the number of pages to fast forward
+ */
+ private int getFastForwardPages() {
+ int pageSize = getPageSize();
+ return pageSize > 0 ? fastForwardRows / pageSize : 0;
+ }
+
+ /**
+ * Enable or disable the fast forward button.
+ *
+ * @param disabled true to disable, false to enable
+ */
+ private void setFastForwardDisabled(boolean disabled) {
+ if (fastForward == null) {
+ return;
+ }
+ if (disabled) {
+ fastForward.setResource(resources.simplePagerFastForwardDisabled());
+ fastForward.getElement().getParentElement().addClassName(
+ style.disabledButton());
+ } else {
+ fastForward.setResource(resources.simplePagerFastForward());
+ fastForward.getElement().getParentElement().removeClassName(
+ style.disabledButton());
+ }
+ }
+
+ /**
+ * Enable or disable the next page buttons.
+ *
+ * @param disabled true to disable, false to enable
+ */
+ private void setNextPageButtonsDisabled(boolean disabled) {
+ if (disabled == nextDisabled) {
+ return;
+ }
+
+ nextDisabled = disabled;
+ if (disabled) {
+ nextPage.setResource(resources.simplePagerNextPageDisabled());
+ nextPage.getElement().getParentElement().addClassName(
+ style.disabledButton());
+ if (lastPage != null) {
+ lastPage.setResource(resources.simplePagerLastPageDisabled());
+ lastPage.getElement().getParentElement().addClassName(
+ style.disabledButton());
+ }
+ } else {
+ nextPage.setResource(resources.simplePagerNextPage());
+ nextPage.getElement().getParentElement().removeClassName(
+ style.disabledButton());
+ if (lastPage != null) {
+ lastPage.setResource(resources.simplePagerLastPage());
+ lastPage.getElement().getParentElement().removeClassName(
+ style.disabledButton());
+ }
+ }
+ }
+
+ /**
+ * Enable or disable the previous page buttons.
+ *
+ * @param disabled true to disable, false to enable
+ */
+ private void setPrevPageButtonsDisabled(boolean disabled) {
+ if (disabled == prevDisabled) {
+ return;
+ }
+
+ prevDisabled = disabled;
+ if (disabled) {
+ firstPage.setResource(resources.simplePagerFirstPageDisabled());
+ firstPage.getElement().getParentElement().addClassName(
+ style.disabledButton());
+ prevPage.setResource(resources.simplePagerPreviousPageDisabled());
+ prevPage.getElement().getParentElement().addClassName(
+ style.disabledButton());
+ } else {
+ firstPage.setResource(resources.simplePagerFirstPage());
+ firstPage.getElement().getParentElement().removeClassName(
+ style.disabledButton());
+ prevPage.setResource(resources.simplePagerPreviousPage());
+ prevPage.getElement().getParentElement().removeClassName(
+ style.disabledButton());
+ }
+ }
+}
--- /dev/null
+<module>
+ <inherits name="com.google.gwt.user.User"/>
+ <inherits name="com.google.gwt.user.theme.standard.Standard"/>
+ <inherits name="com.google.gwt.gears.Gears"/>
+ <inherits name="com.google.gwt.http.HTTP"/>
+ <inherits name="com.google.gwt.json.JSON"/>
+ <inherits name="gwtquery.plugins.droppable.Droppable"/>
+
+ <entry-point class='org.gss_project.gss.web.client.GSS' />
+ <stylesheet src='gss.css' />
+
+ <!-- Rebind the file upload dialog if Gears is installed -->
+ <replace-with class="org.gss_project.gss.web.client.FileUploadGearsDialog">
+ <all>
+ <when-type-is class="org.gss_project.gss.web.client.FileUploadDialog"/>
+ <when-property-is name="gears.installed" value="true"/>
+ <none>
+ <when-property-is name="user.agent" value="ie6"/>
+ <when-property-is name="user.agent" value="ie8"/>
+ </none>
+ </all>
+ </replace-with>
+ <!-- Use a special file upload dialog if Gears is installed on IE -->
+ <replace-with class="org.gss_project.gss.web.client.FileUploadGearsIEDialog">
+ <all>
+ <when-type-is class="org.gss_project.gss.web.client.FileUploadDialog"/>
+ <when-property-is name="gears.installed" value="true"/>
+ <any>
+ <when-property-is name="user.agent" value="ie6"/>
+ <when-property-is name="user.agent" value="ie8"/>
+ </any>
+ </all>
+ </replace-with>
+
+ <source path="client"/>
+</module>
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.user.client.Event.NativePreviewEvent;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.DialogBox;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'about' dialog box.\r
+ */\r
+public class AboutDialog extends DialogBox {\r
+\r
+ /**\r
+ * The widget constructor.\r
+ */\r
+ public AboutDialog() {\r
+ // Set the dialog's caption.\r
+ Configuration conf = (Configuration) GWT.create(Configuration.class);\r
+ String service = conf.serviceName();\r
+ setText("About " + service);\r
+ setAnimationEnabled(true);\r
+ // A VerticalPanel that contains the 'about' label and the 'OK' button.\r
+ final VerticalPanel outer = new VerticalPanel();\r
+\r
+ // Create the 'about' text and set the style.\r
+ final HTML text = new HTML("This is the Web client for the " + service +\r
+ " service. You can use it to store, retrieve and share " +\r
+ "files in the " + service + " server grid. <p>Pithos version: " +\r
+ conf.version() + "<br> A GRNET service designed and implemented by " + "<a href='http://www.grnet.gr'>GRNET</a>" + " and " +\r
+ "<a href='http://www.ebs.gr' target='about'>EBS</a></p>");\r
+ text.setStyleName("gss-AboutText");\r
+ outer.add(text);\r
+\r
+ // Create the 'OK' button, along with a listener that hides the dialog\r
+ // when the button is clicked.\r
+ final Button confirm = new Button("Close", new ClickHandler() {\r
+\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ hide();\r
+ }\r
+ });\r
+ outer.add(confirm);\r
+ outer.setCellHorizontalAlignment(confirm, HasHorizontalAlignment.ALIGN_CENTER);\r
+ outer.setSpacing(8);\r
+ setWidget(outer);\r
+ }\r
+\r
+ @Override\r
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
+ super.onPreviewNativeEvent(preview);\r
+ NativeEvent evt = preview.getNativeEvent();\r
+ if (evt.getType().equals("keydown"))\r
+ // Use the popup's key preview hooks to close the dialog when\r
+ // either enter or escape is pressed.\r
+ switch (evt.getKeyCode()) {\r
+ case KeyCodes.KEY_ENTER:\r
+ case KeyCodes.KEY_ESCAPE:\r
+ hide();\r
+ break;\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.rest.GetCommand;\r
+import org.gss_project.gss.web.client.rest.resource.TagsResource;\r
+\r
+import java.util.List;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.user.client.DeferredCommand;\r
+import com.google.gwt.user.client.Event.NativePreviewEvent;\r
+import com.google.gwt.user.client.ui.Anchor;\r
+import com.google.gwt.user.client.ui.DialogBox;\r
+import com.google.gwt.user.client.ui.FlowPanel;\r
+import com.google.gwt.user.client.ui.Label;\r
+import com.google.gwt.user.client.ui.TabPanel;\r
+import com.google.gwt.user.client.ui.TextBox;\r
+\r
+/**\r
+ * Abstract class, parent of all 'File properties' dialog boxes.\r
+ *\r
+ * @author droutsis\r
+ */\r
+public abstract class AbstractPropertiesDialog extends DialogBox {\r
+\r
+ protected static final String MULTIPLE_VALUES_TEXT = "(Multiple values)";\r
+\r
+ /**\r
+ * Text box with the tags associated with the file\r
+ */\r
+ protected TextBox tags = new TextBox();\r
+\r
+ protected String initialTagText;\r
+\r
+ /**\r
+ * A FlowPanel with all user tags\r
+ */\r
+ protected FlowPanel allTagsContent;\r
+\r
+\r
+ protected TabPanel inner = null;\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ *\r
+ */\r
+ public AbstractPropertiesDialog() {\r
+\r
+ // Enable IE selection for the dialog (must disable it upon closing it)\r
+ GSS.enableIESelection();\r
+\r
+ setAnimationEnabled(true);\r
+\r
+ }\r
+ /**\r
+ * Retrieves all user tags from the server and updates the FlowPanel\r
+ *\r
+ * @param userId\r
+ */\r
+ protected void updateTags() {\r
+ GetCommand<TagsResource> tc = new GetCommand<TagsResource>(TagsResource.class, GSS.get().getCurrentUserResource().getTagsPath(),null) {\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ allTagsContent.clear();\r
+ TagsResource tagr = getResult();\r
+ List<String> userTags = tagr.getTags();\r
+ Anchor tag = null;\r
+ for(String usrTag : userTags){\r
+ tag = new Anchor(usrTag.toString(), false);\r
+ tag.addStyleName("gss-tag");\r
+ allTagsContent.add(tag);\r
+ Label separator = new Label(", ");\r
+ separator.addStyleName("gss-tag");\r
+ allTagsContent.add(separator);\r
+ tag.addClickHandler( new ClickHandler() {\r
+\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ String existing = tags.getText();\r
+ if (MULTIPLE_VALUES_TEXT.equals(existing)) existing = "";\r
+ String newTag = ((Anchor) event.getSource()).getText().trim();\r
+ // insert the new tag only if it is not in the list\r
+ // already\r
+ if (existing.indexOf(newTag) == -1 && !existing.trim().endsWith(newTag))\r
+ tags.setText(existing.trim()\r
+ + (existing.length() > 0 ? ", " : "")\r
+ + newTag);\r
+ }\r
+ });\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ GSS.get().displayError("Unable to fetch user tags");\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(tc);\r
+\r
+ }\r
+\r
+ /**\r
+ * Accepts any change and updates the file\r
+ *\r
+ */\r
+ protected abstract void accept();\r
+\r
+ @Override\r
+ @SuppressWarnings("fallthrough")\r
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
+ super.onPreviewNativeEvent(preview);\r
+\r
+ NativeEvent evt = preview.getNativeEvent();\r
+ if (evt.getType().equals("keydown"))\r
+ // Use the popup's key preview hooks to close the dialog when either\r
+ // enter or escape is pressed.\r
+ switch (evt.getKeyCode()) {\r
+ case KeyCodes.KEY_ENTER:\r
+ accept();\r
+ case KeyCodes.KEY_ESCAPE:\r
+ closeDialog();\r
+ break;\r
+ }\r
+ }\r
+\r
+\r
+\r
+ public void selectTab(int _tab) {\r
+ inner.selectTab(_tab);\r
+ }\r
+\r
+\r
+ /**\r
+ * Enables IE selection prevention and hides the dialog\r
+ * (we disable the prevention on creation of the dialog)\r
+ */\r
+ public void closeDialog() {\r
+ GSS.preventIESelection();\r
+ hide();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.CellTreeViewModel.ClearSelection;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.MyFolderResource;
+import org.gss_project.gss.web.client.rest.resource.OtherUserResource;
+import org.gss_project.gss.web.client.rest.resource.OthersFolderResource;
+import org.gss_project.gss.web.client.rest.resource.OthersResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashFolderResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTree;
+
+import java.util.Arrays;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.resources.client.ImageResource.ImageOptions;
+import com.google.gwt.user.cellview.client.CellTree;
+import com.google.gwt.user.cellview.client.TreeNode;
+import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.Tree;
+import com.google.gwt.view.client.ProvidesKey;
+import com.google.gwt.view.client.SelectionChangeEvent;
+import com.google.gwt.view.client.SingleSelectionModel;
+import com.google.gwt.view.client.TreeViewModel;
+import com.google.gwt.view.client.SelectionChangeEvent.Handler;
+import com.google.gwt.view.client.TreeViewModel.NodeInfo;
+
+
+/**
+ * @author kman
+ *
+ */
+public class CellTreeView extends Composite{
+ public static final boolean DONE = false;
+ Images images;
+
+ SingleSelectionModel<RestResource> selectionModel = new SingleSelectionModel<RestResource>(new ProvidesKey<RestResource>() {
+
+ @Override
+ public Object getKey(RestResource item) {
+ return item.getClass().getName()+":"+item.getUri();
+ }});
+ FolderContextMenu menu;
+
+
+ MyFolderResource myFolders=null;
+ TrashResource trash = null;
+ SharedResource myshared = null;
+ OthersResource others = null;
+
+ CellTreeViewModel model;
+ CellTreeViewUtils utils;
+
+ public interface Images extends ClientBundle,Tree.Resources, FolderContextMenu.Images {
+
+ @Source("org/gss_project/gss/resources/folder_home.png")
+ ImageResource home();
+
+ @Source("org/gss_project/gss/resources/folder_yellow.png")
+ ImageResource folderYellow();
+
+ @Source("org/gss_project/gss/resources/mimetypes/document.png")
+ ImageResource document();
+
+ @Source("org/gss_project/gss/resources/internet.png")
+ ImageResource othersShared();
+
+ @Source("org/gss_project/gss/resources/edit_user.png")
+ ImageResource myShared();
+
+ @Source("org/gss_project/gss/resources/folder_user.png")
+ ImageResource sharedFolder();
+
+ @Source("org/gss_project/gss/resources/trashcan_empty.png")
+ ImageResource trash();
+ }
+ DragAndDropCellTree tree;
+ /*public interface BasicResources extends CellTree.BasicResources{
+ @ImageOptions(flipRtl = true)
+ @Source("cellTreeLoadingBasic.gif")
+ ImageResource cellTreeLoading();
+
+ @Source({"GssCellTreeBasic.css"})
+ CellTree.Style cellTreeStyle();
+ }*/
+ public interface BasicResources extends CellTree.Resources {
+
+ @ImageOptions(flipRtl = true)
+ @Source("cellTreeClosedItem.gif")
+ ImageResource cellTreeClosedItem();
+
+ @ImageOptions(flipRtl = true)
+ @Source("cellTreeLoadingBasic.gif")
+ ImageResource cellTreeLoading();
+
+ @ImageOptions(flipRtl = true)
+ @Source("cellTreeOpenItem.gif")
+ ImageResource cellTreeOpenItem();
+
+ //@Source({CellTree.Style.DEFAULT_CSS,"GssCellTreeBasic.css"})
+ @Source({"GssCellTreeBasic.css"})
+ CellTree.Style cellTreeStyle();
+ }
+ /**
+ *
+ */
+ public CellTreeView(final Images _images) {
+ images = _images;
+ model = new CellTreeViewModel(images,selectionModel);
+ /*
+ * Create the tree using the model. We use <code>null</code> as the default
+ * value of the root node. The default value will be passed to
+ * CustomTreeModel#getNodeInfo();
+ */
+ CellTree.Resources res = GWT.create(BasicResources.class);
+ tree = new DragAndDropCellTree(model,null, res){
+ @Override
+ public void onBrowserEvent(Event event) {
+ // TODO Auto-generated method stub
+ super.onBrowserEvent(event);
+ }
+ };
+ utils=new CellTreeViewUtils(tree);
+ tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
+ /*tree.addOpenHandler(new OpenHandler<TreeNode>() {
+
+ @Override
+ public void onOpen(OpenEvent<TreeNode> event) {
+ Window.alert("[NODE OPENED]"+event.getTarget());
+
+ }
+ });
+ tree.addOverDroppableHandler(new OverDroppableEventHandler() {
+
+ @Override
+ public void onOverDroppable(OverDroppableEvent event) {
+ GWT.log("OVER:"+event);
+
+ }
+ });
+ tree.addAttachHandler(new AttachEvent.Handler() {
+
+ @Override
+ public void onAttachOrDetach(AttachEvent event) {
+ GWT.log("ATTACH:"+event.getSource());
+
+ }
+ });*/
+ Handler selectionHandler = new SelectionChangeEvent.Handler() {
+ @Override
+ public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
+ NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
+ if(nodeInfo==null || nodeInfo.getValueUpdater()==null){
+ GSS.get().showFileList(getSelection());
+ }
+ else
+ nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
+ GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
+
+
+ }
+ };
+ selectionModel.addSelectionChangeHandler(selectionHandler);
+ sinkEvents(Event.ONCONTEXTMENU);
+ sinkEvents(Event.ONMOUSEUP);
+ initWidget(tree);
+ FolderResource loadingResource = new FolderResource("loading");
+ loadingResource.setName("Loading....");
+ loadingResource.setShared(false);
+ RestResourceWrapper loading = new RestResourceWrapper(loadingResource);
+ model.getRootNodes().setList(Arrays.asList((RestResource)loading));
+
+ DeferredCommand.addCommand(new IncrementalCommand() {
+
+ @Override
+ public boolean execute() {
+ return fetchRootFolders();
+ }
+ });
+ }
+
+ public void updateNode(RestResource resource){
+ NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(resource);
+
+ if(nodeInfo!=null){
+ if(nodeInfo.getValueUpdater()==null){}
+ else
+ nodeInfo.getValueUpdater().update(resource);
+ }
+ }
+
+ public void updateNodeChildren(final RestResource resource){
+
+ if(resource instanceof RestResourceWrapper){
+ boolean updated=false;
+ if(((RestResourceWrapper)resource).getResource().getFolders().size()==0){
+ if(((RestResourceWrapper)resource).getResource().getParentURI().equals(getMyFolders().getUri())){
+ updateNodeChildren(getMyFolders().getUri());
+ return;
+ }
+ if(model.getMymap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
+ model.getMymap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
+ updated=true;
+ }
+ if(model.getOthersmap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
+ model.getOthersmap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
+ updated=true;
+ }
+ if(model.getSharedmap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
+ model.getSharedmap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
+ updated=true;
+ }
+ if(updated){
+ if(utils.doesSharedNodeContainsResourceIn1stLevel(resource.getUri())){
+ updateMySharedNode();
+ }
+ else if(tree.getRootTreeNode().isChildOpen(2)){
+ utils.refreshNodeContainingResource(tree.getRootTreeNode().setChildOpen(2,true),resource.getUri());
+ }
+ //return;
+ }
+ }
+ }
+
+ utils.refreshNodeContainingResource(resource);
+ if(utils.doesSharedNodeContainsResourceIn1stLevel(resource.getUri())){
+ updateMySharedNode();
+ }
+ else if(tree.getRootTreeNode().isChildOpen(2)){
+ GWT.log("REFRESH THE OTHER WAY 2:"+resource);
+ utils.refreshNodeContainingResource(tree.getRootTreeNode().setChildOpen(2,true),resource.getUri());
+ }
+
+ }
+ public void updateNodeChildrenForRemove(final String resource){
+ GWT.log("********************************");
+ GWT.log("[UPDATENODECHILDREN]"+resource);
+ GWT.log("********************************");
+ boolean updated=false;
+ TreeNode node=null;
+ TreeNode sharedNode=null;
+ if(tree.getRootTreeNode().isChildOpen(0)){
+ node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(0,true), resource);
+ }
+ GWT.log("CHECK NODE1:"+node+" "+resource);
+
+ if(tree.getRootTreeNode().isChildOpen(2)){
+ GWT.log("CHECK NODE2:"+node);
+ if(node==null)
+ node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(2,true), resource);
+
+ }
+ if(node==null)
+ if(tree.getRootTreeNode().isChildOpen(3)){
+ GWT.log("CHECK NODE3:"+node);
+ node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(3,true), resource);
+ }
+ if(node != null && node.getValue() instanceof RestResourceWrapper){
+ GWT.log("*********************"+((RestResourceWrapper) node.getValue()).getResource().getFolders().size());
+ RestResourceWrapper wrapper = (RestResourceWrapper) node.getValue();
+ if(wrapper.getResource().countNotDeletedSubfolders()==1||wrapper.getResource().countNotDeletedSubfolders()==0){
+ updateNodeChildren(((RestResourceWrapper) node.getValue()).getResource().getParentURI());
+ if(((RestResourceWrapper) node.getValue()).getResource().getParentURI().equals(myFolders.getUri())){
+ if(utils.doesSharedNodeContainsResourceIn1stLevel(resource)||utils.doesSharedNodeContainsResourceIn2ndLevel(resource)){
+ updateMySharedNode();
+ }
+ }
+
+ }
+ else
+ updateNodeChildren(((RestResource) node.getValue()).getUri());
+ return;
+ }
+ updateNodeChildren(resource);
+ }
+ public void updateNodeChildren(final String resource){
+
+
+ GWT.log("REFRESH THE OTHER WAY");
+ utils.refreshNodeContainingResource(resource);
+ if(utils.doesSharedNodeContainsResourceIn1stLevel(resource)||utils.doesSharedNodeContainsResourceIn2ndLevel(resource)){
+ GWT.log("REFRESH THE OTHER WAY 1:"+resource);
+ updateMySharedNode();
+ }
+ else if(tree.getRootTreeNode().isChildOpen(2)){
+ GWT.log("REFRESH THE OTHER WAY 2:"+resource);
+ utils.refreshNodeContainingResource(tree.getRootTreeNode().setChildOpen(2,true),resource);
+ }
+ }
+
+ protected void showPopup(final int x, final int y) {
+ if (selectionModel.getSelectedObject() == null)
+ return;
+ if (menu != null)
+ menu.hide();
+ menu = new FolderContextMenu(images);
+ menu.setPopupPosition(x, y);
+ menu.show();
+ }
+ private boolean init=false;
+ public boolean fetchRootFolders() {
+ UserResource userResource = GSS.get().getCurrentUserResource();
+ if (userResource == null)
+ return !DONE;
+ if(!init){
+ final String path = userResource.getFilesPath();
+ GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
+
+ @Override
+ public void onComplete() {
+ myFolders = new MyFolderResource(getResult());
+ //selectionModel.setSelected(myFolders, true);
+ //rootNodes.setList(Arrays.asList((RestResource)rootResource));
+ //tree.getRootTreeNode().setChildOpen(0, true);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching root folder", t);
+ GSS.get().displayError("Unable to fetch root folder");
+ }
+
+ };
+ DeferredCommand.addCommand(gf);
+ DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
+ @Override
+ public void onComplete() {
+ trash = getResult();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ // On IE status code 1223 may be returned instead of 204.
+ if(statusCode == 204 || statusCode == 1223){
+ trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
+ }
+ else{
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
+ trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
+ }
+ }
+ }
+ });
+ GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
+
+ @Override
+ public void onComplete() {
+ myshared=getResult();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching Shared Root folder", t);
+ GSS.get().displayError("Unable to fetch Shared Root folder");
+ }
+ };
+ DeferredCommand.addCommand(gs);
+ GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
+ userResource.getOthersPath(), null) {
+
+ @Override
+ public void onComplete() {
+ others = getResult();
+ GSS.get().removeGlassPanel();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching Others Root folder", t);
+ GSS.get().displayError("Unable to fetch Others Root folder");
+ }
+ };
+ DeferredCommand.addCommand(go);
+ }
+ if(myFolders==null||trash==null||myshared==null||others==null)
+ return !DONE;
+ model.getRootNodes().setList(Arrays.asList((RestResource)myFolders,(RestResource)trash,(RestResource)myshared,(RestResource)others));
+ tree.getRootTreeNode().setChildOpen(0, true);
+ selectionModel.setSelected(myFolders, true);
+ return DONE;
+ }
+
+ public Images getImages() {
+ return images;
+ }
+
+
+ public void updateTrashNode(){
+ DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
+ @Override
+ public void onComplete() {
+ trash = getResult();
+ boolean trashIsOpen = tree.getRootTreeNode().isChildOpen(1);
+ model.getRootNodes().getList().set(1, trash);
+ model.getRootNodes().refresh();
+ tree.getRootTreeNode().setChildOpen(1, true);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ // On IE status code 1223 may be returned instead of 204.
+ if(statusCode == 204 || statusCode == 1223){
+ trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
+ model.getRootNodes().getList().set(1, trash);
+ //model.getRootNodes().refresh();
+ }
+ else{
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
+ trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
+ model.getRootNodes().getList().set(1, trash);
+ //model.getRootNodes().refresh();
+ }
+ }
+ }
+ });
+ }
+
+ public void updateRootNode(){
+ final String path = GSS.get().getCurrentUserResource().getFilesPath();
+ GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
+
+ @Override
+ public void onComplete() {
+ myFolders = new MyFolderResource(getResult());
+ model.getRootNodes().getList().set(0, myFolders);
+ model.getRootNodes().refresh();
+ tree.getRootTreeNode().setChildOpen(0, true);
+
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching root folder", t);
+ GSS.get().displayError("Unable to fetch root folder");
+ }
+
+ };
+ DeferredCommand.addCommand(gf);
+ }
+
+ public void updateMySharedNode(){
+ GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, GSS.get().getCurrentUserResource().getSharedPath(), null) {
+
+ @Override
+ public void onComplete() {
+ myshared=getResult();
+ model.getRootNodes().getList().set(2, myshared);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching Shared Root folder", t);
+ GSS.get().displayError("Unable to fetch Shared Root folder");
+ }
+ };
+ DeferredCommand.addCommand(gs);
+ }
+
+ public void updateOtherNode(){
+ GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
+ GSS.get().getCurrentUserResource().getOthersPath(), null) {
+
+ @Override
+ public void onComplete() {
+ others = getResult();
+ model.getRootNodes().getList().set(3, others);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching Others Root folder", t);
+ GSS.get().displayError("Unable to fetch Others Root folder");
+ }
+ };
+ DeferredCommand.addCommand(go);
+ }
+
+
+ public RestResource getSelection(){
+ return selectionModel.getSelectedObject();
+ }
+
+ public void clearSelection(){
+ if(GSS.get().getCurrentSelection().equals(getSelection()))
+ GSS.get().setCurrentSelection(null);
+ selectionModel.setSelected(getSelection(), false);
+ }
+
+
+ /**
+ * Retrieve the myFolders.
+ *
+ * @return the myFolders
+ */
+ public MyFolderResource getMyFolders() {
+ return myFolders;
+ }
+
+
+ /**
+ * Retrieve the myshared.
+ *
+ * @return the myshared
+ */
+ public SharedResource getMyshared() {
+ return myshared;
+ }
+
+
+ /**
+ * Retrieve the trash.
+ *
+ * @return the trash
+ */
+ public TrashResource getTrash() {
+ return trash;
+ }
+
+
+ /**
+ * Retrieve the others.
+ *
+ * @return the others
+ */
+ public OthersResource getOthers() {
+ return others;
+ }
+
+
+ /**
+ * Retrieve the model.
+ *
+ * @return the model
+ */
+ public TreeViewModel getModel() {
+ return model;
+ }
+
+
+
+ /**
+ * Retrieve the utils.
+ *
+ * @return the utils
+ */
+ public CellTreeViewUtils getUtils() {
+ return utils;
+ }
+
+ public interface RefreshHandler{
+ void onRefresh();
+ }
+
+
+ public boolean isTrashOrTrashFolderSelected(){
+ return (getSelection() instanceof TrashResource) || (getSelection() instanceof TrashFolderResource);
+ }
+
+ public OtherUserResource getOtherUserResourceOfOtherFolder(OthersFolderResource res){
+ TreeNode n = utils.getNodeContainingResource(tree.getRootTreeNode().setChildOpen(3, true), res);
+
+ if(n!=null){
+ if(n.getValue() instanceof OtherUserResource)
+ return (OtherUserResource) n.getValue();
+ TreeNode parent = n.getParent();
+
+ while (parent!=null){
+ if(parent.getValue() instanceof OtherUserResource)
+ return (OtherUserResource) parent.getValue();
+ parent = parent.getParent();
+ }
+ }
+ return null;
+ }
+
+ public void refreshCurrentNode(boolean clearSelection){
+ NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
+ if(nodeInfo==null || nodeInfo.getValueUpdater()==null){
+ GSS.get().showFileList(getSelection(),clearSelection);
+ }
+ else{
+ if(!clearSelection)
+ ((ClearSelection)nodeInfo.getValueUpdater()).setClearSelection(clearSelection);
+ nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+import org.gss_project.gss.web.client.CellTreeView.Images;
+import org.gss_project.gss.web.client.CellTreeView.RefreshHandler;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.MyFolderResource;
+import org.gss_project.gss.web.client.rest.resource.OtherUserResource;
+import org.gss_project.gss.web.client.rest.resource.OthersFolderResource;
+import org.gss_project.gss.web.client.rest.resource.OthersResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+import org.gss_project.gss.web.client.rest.resource.SharedFolderResource;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashFolderResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import gwtquery.plugins.draggable.client.DragAndDropManager;
+import gwtquery.plugins.draggable.client.DraggableOptions;
+import gwtquery.plugins.draggable.client.StopDragException;
+import gwtquery.plugins.draggable.client.DraggableOptions.CursorAt;
+import gwtquery.plugins.draggable.client.DraggableOptions.DragFunction;
+import gwtquery.plugins.draggable.client.DraggableOptions.RevertOption;
+import gwtquery.plugins.draggable.client.events.DragContext;
+import gwtquery.plugins.droppable.client.DroppableOptions;
+import gwtquery.plugins.droppable.client.DroppableOptions.DroppableFunction;
+import gwtquery.plugins.droppable.client.events.DragAndDropContext;
+import gwtquery.plugins.droppable.client.gwt.DragAndDropNodeInfo;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.cell.client.AbstractCell;
+import com.google.gwt.cell.client.Cell;
+import com.google.gwt.cell.client.ValueUpdater;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Style.Cursor;
+import com.google.gwt.safehtml.client.SafeHtmlTemplates;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.view.client.AsyncDataProvider;
+import com.google.gwt.view.client.HasData;
+import com.google.gwt.view.client.ListDataProvider;
+import com.google.gwt.view.client.ProvidesKey;
+import com.google.gwt.view.client.SingleSelectionModel;
+import com.google.gwt.view.client.TreeViewModel;
+
+
+
+/**
+ * @author kman
+ *
+ */
+public class CellTreeViewModel implements TreeViewModel{
+
+ private final ListDataProvider<RestResource> rootNodes = new ListDataProvider<RestResource>();
+ private Map<String,FolderResource> folderCache=new HashMap<String, FolderResource>();
+ final Images images;
+ SingleSelectionModel<RestResource> selectionModel;
+ Map<String, MyFolderDataProvider> mymap = new HashMap<String, MyFolderDataProvider>();
+ Map<String, MyFolderDataProvider> sharedmap = new HashMap<String, MyFolderDataProvider>();
+ Map<String, MyFolderDataProvider> othersmap = new HashMap<String, MyFolderDataProvider>();
+ static interface Templates extends SafeHtmlTemplates {
+ Templates INSTANCE = GWT.create(Templates.class);
+
+ @Template(" <div id='dragHelper' class='{0}'></div>")
+ SafeHtml outerHelper(String cssClassName);
+ }
+
+ void configureDragOperation(final DraggableOptions options) {
+
+ // set a custom element as drag helper. The content of the helper will be
+ // set when the drag will start
+ options.setHelper($(Templates.INSTANCE.outerHelper(
+ "drag").asString()));
+ // opacity of the drag helper
+ options.setOpacity((float) 0.9);
+ // cursor during the drag operation
+ options.setCursor(Cursor.MOVE);
+ // the cell being greater than the helper, force the position of the
+ // helper on the mouse cursor.
+ options.setCursorAt(new CursorAt(10, 10, null, null));
+ // append the helper to the body element
+ options.setAppendTo("body");
+ options.setCancel("select");
+ // set the revert option
+ options.setRevert(RevertOption.ON_INVALID_DROP);
+
+ options.setOnBeforeDragStart(new DragFunction() {
+
+ @Override
+ public void f(DragContext context) {
+ RestResource value = context.getDraggableData();
+ if(!CellTreeViewModel.this.selectionModel.isSelected(value)){
+ throw new StopDragException();
+ }
+ if(value instanceof TrashResource || value instanceof SharedResource || value instanceof OthersResource || value instanceof OtherUserResource){
+ throw new StopDragException();
+ }
+
+ }
+ });
+ // use a Function to fill the content of the helper
+ // we could also add a DragStartEventHandler on the DragAndDropTreeCell and
+ // DragAndDropCellList.
+
+ options.setOnDragStart(new DragFunction() {
+ public void f(DragContext context) {
+ RestResourceWrapper memberInfo = context.getDraggableData();
+ context.getHelper().setInnerHTML(memberInfo.getName());
+ }
+ });
+
+ }
+
+ /**
+ *
+ */
+ public CellTreeViewModel(final Images _images,SingleSelectionModel<RestResource> selectionModel ) {
+ super();
+ images=_images;
+ this.selectionModel=selectionModel;
+ }
+
+ private final Cell<RestResource> departmentCell = new AbstractCell<RestResource>("contextmenu"){
+
+ @Override
+ public void render(com.google.gwt.cell.client.Cell.Context arg0, RestResource arg1, SafeHtmlBuilder arg2) {
+ String id = null;
+ String html = null;
+ String name = null;
+ if(arg1 instanceof TrashFolderResource){
+ html = AbstractImagePrototype.create(images.folderYellow()).getHTML();
+ FolderResource res = ((RestResourceWrapper)arg1).getResource();
+ name = res.getName();
+ id = res.getParentName() +"."+name;
+ }
+ else if(arg1 instanceof RestResourceWrapper){
+ FolderResource res = ((RestResourceWrapper)arg1).getResource();
+ if(res.isShared())
+ html = AbstractImagePrototype.create(images.sharedFolder()).getHTML();
+ else if(res.getParentName()==null){
+ html = AbstractImagePrototype.create(images.home()).getHTML();
+ }
+ else
+ html = AbstractImagePrototype.create(images.folderYellow()).getHTML();
+ name = res.getName();
+ if(res.getParentName() != null){
+ id = res.getParentName()+"."+name;
+ }else{
+ id = name;
+ }
+
+ }
+ else if(arg1 instanceof TrashResource){
+ html = AbstractImagePrototype.create(images.trash()).getHTML();
+ name="Trash";
+ id = name;
+ }
+
+ else if(arg1 instanceof SharedResource){
+ html = AbstractImagePrototype.create(images.myShared()).getHTML();
+ name = "My Shared";
+ id = name;
+ }
+ else if(arg1 instanceof OthersResource){
+ html = AbstractImagePrototype.create(images.othersShared()).getHTML();
+ name = "Other's Shared";
+ id = "others";
+ }
+ else if(arg1 instanceof OtherUserResource){
+ html = AbstractImagePrototype.create(images.permUser()).getHTML();
+ name = ((OtherUserResource)arg1).getName();
+ id = name;
+ }
+ arg2.appendHtmlConstant(html);
+ arg2.append(FileList.Templates.INSTANCE.spanWithIdAndClass(id, "papala", name));
+ }
+
+ public void onBrowserEvent(Cell.Context context, com.google.gwt.dom.client.Element parent, RestResource value, com.google.gwt.dom.client.NativeEvent event, com.google.gwt.cell.client.ValueUpdater<RestResource> valueUpdater) {
+ if(event.getType().equals("contextmenu")){
+ selectionModel.setSelected(value, true);
+ GSS.get().setCurrentSelection(value);
+ GSS.get().getTreeView().showPopup(event.getClientX(), event.getClientY());
+ }
+ };
+
+ };
+
+
+ @Override
+ public <T> NodeInfo<?> getNodeInfo(final T value) {
+
+ if(value==null){
+ DragAndDropNodeInfo n = new DragAndDropNodeInfo<RestResource>(getRootNodes(), departmentCell,
+ selectionModel, null);
+ configureFolderDrop(n);
+ configureDragOperation(n.getDraggableOptions());
+ return n;
+ }
+ else if (value instanceof MyFolderResource) {
+ // Second level.
+ MyFolderDataProvider dataProvider = new MyFolderDataProvider(
+ ((MyFolderResource) value),MyFolderResource.class);
+ DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
+ selectionModel, new ResourceValueUpdater());
+ mymap.put(((MyFolderResource) value).getUri(), dataProvider);
+
+ // permission cell are not draggable
+ //n.setCellDroppableOnly();
+ configureFolderDrop(n);
+ configureDragOperation(n.getDraggableOptions());
+
+ return n;
+ }
+ else if (value instanceof SharedResource) {
+ // Second level.
+ MyFolderDataProvider dataProvider = new MyFolderDataProvider(
+ ((SharedResource) value), SharedFolderResource.class);
+ sharedmap.put(((SharedResource) value).getUri(), dataProvider);
+ DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
+ selectionModel, new ResourceValueUpdater());
+ configureFolderDrop(n);
+ configureDragOperation(n.getDraggableOptions());
+ return n;
+ }
+ else if (value instanceof TrashResource) {
+ // Second level.
+ ListDataProvider<RestResource> trashProvider = new ListDataProvider<RestResource>();
+ List<RestResource> r = new ArrayList<RestResource>();
+ for(FolderResource f : GSS.get().getTreeView().getTrash().getFolders()){
+ r.add(new TrashFolderResource(f));
+ }
+ trashProvider.setList(r);
+ DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(trashProvider, departmentCell,
+ selectionModel, new ResourceValueUpdater());
+ configureFolderDrop(n);
+ configureDragOperation(n.getDraggableOptions());
+ return n;
+ }
+ else if (value instanceof OthersResource) {
+ // Second level.
+ OthersDataProvider dataProvider = new OthersDataProvider(
+ ((OthersResource) value), SharedFolderResource.class);
+ DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
+ selectionModel, null);
+ configureFolderDrop(n);
+ configureDragOperation(n.getDraggableOptions());
+ return n;
+ }
+ else if (value instanceof SharedFolderResource) {
+ // Second level.
+ MyFolderDataProvider dataProvider = new MyFolderDataProvider(
+ ((SharedFolderResource) value),SharedFolderResource.class);
+ DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
+ selectionModel, new ResourceValueUpdater());
+ sharedmap.put(((SharedFolderResource) value).getUri(), dataProvider);
+ configureFolderDrop(n);
+ configureDragOperation(n.getDraggableOptions());
+ return n;
+ }
+ else if (value instanceof OthersFolderResource) {
+ // Second level.
+ MyFolderDataProvider dataProvider = new MyFolderDataProvider(
+ ((OthersFolderResource) value),OthersFolderResource.class);
+ DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
+ selectionModel, new ResourceValueUpdater());
+ //nodeInfos.put(((OthersFolderResource) value).getUri(), n);
+ othersmap.put(((OthersFolderResource) value).getUri(), dataProvider);
+ configureFolderDrop(n);
+ configureDragOperation(n.getDraggableOptions());
+ return n;
+ }
+ else if (value instanceof OtherUserResource) {
+ // Second level.
+ MyFolderDataProvider dataProvider = new MyFolderDataProvider(
+ ((OtherUserResource) value),OthersFolderResource.class);
+ DragAndDropNodeInfo<RestResource> n = new DragAndDropNodeInfo<RestResource>(dataProvider, departmentCell,
+ selectionModel, new ResourceValueUpdater());
+ configureFolderDrop(n);
+ configureDragOperation(n.getDraggableOptions());
+ return n;
+ }
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ private void configureFolderDrop(DragAndDropNodeInfo<RestResource> n){
+ DroppableOptions options = n.getDroppableOptions();
+ options.setDroppableHoverClass("droppableHover");
+ // use a DroppableFunction here. We can also add a DropHandler in the tree
+ // itself
+ options.setOnOver(new DroppableFunction() {
+
+ @Override
+ public void f(final DragAndDropContext context) {
+ if(context.getDroppableData()!=null && context.getDroppableData() instanceof RestResource){
+
+ GSS.get().getTreeView().getUtils().openNodeContainingResource((RestResource) context.getDroppableData(), new RefreshHandler() {
+
+ @Override
+ public void onRefresh() {
+
+ DragAndDropManager.getInstance().update(context);//initialize(context, GQueryUi.Event.create(com.google.gwt.user.client.Event.getCurrentEvent()));
+
+ }
+ });
+
+ }
+ }
+ });
+ options.setOnDrop(new DroppableFunction() {
+
+ public void f(DragAndDropContext context) {
+
+ DnDFolderPopupMenu popup ;
+ if(context.getDraggableData() instanceof FileResource){
+ if(context.getDroppableData() instanceof RestResourceWrapper)
+ popup = new DnDFolderPopupMenu(images, ((RestResourceWrapper) context.getDroppableData()).getResource(), Arrays.asList(context.getDraggableData()));
+ else
+ popup = new DnDFolderPopupMenu(images, null, Arrays.asList(context.getDraggableData()));
+ }
+
+ else{
+ if(context.getDroppableData() instanceof RestResourceWrapper)
+ popup = new DnDFolderPopupMenu(images, ((RestResourceWrapper) context.getDroppableData()).getResource(), context.getDraggableData());
+ else
+ popup = new DnDFolderPopupMenu(images, null, context.getDraggableData());
+ }
+
+ int left = context.getDroppable().getAbsoluteLeft() + 40;
+ int top = context.getDroppable().getAbsoluteTop() + 20;
+ popup.setPopupPosition(left, top);
+
+ popup.show();
+ }
+ });
+ }
+
+ @Override
+ public boolean isLeaf(Object value) {
+ if(value instanceof RestResourceWrapper)
+ return ((RestResourceWrapper)value).getResource().getFolders().size()==0;
+ else if(value instanceof TrashResource)
+ return ((TrashResource)value).getFolders().size()==0;
+ else if(value instanceof SharedResource)
+ return ((SharedResource)value).getFolders().size()==0;
+ else if(value instanceof OthersResource)
+ return ((OthersResource)value).getOtherUsers().size()==0;
+ else if(value instanceof OtherUserResource)
+ return ((OtherUserResource)value).getFolders().size()==0;
+ return false;
+ }
+
+ /**
+ * Retrieve the selectionModel.
+ *
+ * @return the selectionModel
+ */
+ public SingleSelectionModel<RestResource> getSelectionModel() {
+ return selectionModel;
+ }
+ static interface ClearSelection{
+ public void setClearSelection(boolean clearSelection);
+ }
+ class ResourceValueUpdater implements ValueUpdater<RestResource>,ClearSelection{
+ boolean clearSelection=true;
+
+
+ /**
+ * Modify the clearSelection.
+ *
+ * @param clearSelection the clearSelection to set
+ */
+ public void setClearSelection(boolean clearSelection) {
+ this.clearSelection = clearSelection;
+ }
+ @Override
+ public void update(final RestResource value) {
+ if(value instanceof MyFolderResource){
+ GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, value.getUri(), null) {
+
+ @Override
+ public void onComplete() {
+ FolderResource rootResource = getResult();
+ //((MyFolderResource)value).getResource().setFiles(rootResource.getFiles());
+ ((MyFolderResource)value).setResource(rootResource);
+ if(GSS.get().getTreeView().getSelection().getUri().equals(value.getUri()))
+ selectionModel.setSelected(value, true);
+ GSS.get().onResourceUpdate(value,clearSelection);
+
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching root folder", t);
+ GSS.get().displayError("Unable to fetch root folder");
+ }
+
+ };
+ DeferredCommand.addCommand(gf);
+ }
+ else if(value instanceof TrashResource){
+ DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
+ @Override
+ public void onComplete() {
+ //trash = getResult();
+ ((TrashResource)value).setFolders(getResult().getFolders());
+ ((TrashResource)value).setFiles(getResult().getFiles());
+ for(RestResource r : getRootNodes().getList()){
+ if(r instanceof TrashResource)
+ getRootNodes().getList().set(getRootNodes().getList().indexOf(r),GSS.get().getTreeView().getTrash());
+ }
+ GSS.get().getTreeView().updateNodeChildren(GSS.get().getTreeView().getTrash());
+ //GSS.get().showFileList(true);
+ GSS.get().onResourceUpdate(value,clearSelection);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ // On IE status code 1223 may be returned instead of 204.
+ if(statusCode == 204 || statusCode == 1223){
+ ((TrashResource)value).setFolders(new ArrayList<FolderResource>());
+ ((TrashResource)value).setFiles(new ArrayList<FileResource>());
+ }
+ else{
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
+ //GSS.get().getTreeView().getTrash() = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
+ }
+ }
+ }
+ });
+ }
+ else if(value instanceof OthersFolderResource){
+ GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, value.getUri(), null) {
+
+ @Override
+ public void onComplete() {
+ FolderResource rootResource = getResult();
+ //((MyFolderResource)value).getResource().setFiles(rootResource.getFiles());
+ ((OthersFolderResource)value).setResource(rootResource);
+ if(GSS.get().getTreeView().getSelection().getUri().equals(value.getUri()))
+ selectionModel.setSelected(value, true);
+ GSS.get().onResourceUpdate(value,clearSelection);
+
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching root folder", t);
+ GSS.get().displayError("Unable to fetch root folder");
+ }
+
+ };
+ DeferredCommand.addCommand(gf);
+ }
+ else if(value instanceof SharedFolderResource){
+ GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, value.getUri(), null) {
+
+ @Override
+ public void onComplete() {
+ FolderResource rootResource = getResult();
+ //((MyFolderResource)value).getResource().setFiles(rootResource.getFiles());
+ ((SharedFolderResource)value).setResource(rootResource);
+ if(GSS.get().getTreeView().getSelection().getUri().equals(value.getUri()))
+ selectionModel.setSelected(value, true);
+ GSS.get().onResourceUpdate(value,clearSelection);
+
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching root folder", t);
+ GSS.get().displayError("Unable to fetch root folder");
+ }
+
+ };
+ DeferredCommand.addCommand(gf);
+ }
+ else if(value instanceof SharedResource){
+ GetCommand<SharedResource> gf = new GetCommand<SharedResource>(SharedResource.class, value.getUri(), null) {
+
+ @Override
+ public void onComplete() {
+ SharedResource rootResource = getResult();
+ ((SharedResource)value).setFolders(getResult().getFolders());
+ ((SharedResource)value).setFiles(getResult().getFiles());
+
+ if(GSS.get().getTreeView().getSelection().getUri().equals(value.getUri()))
+ selectionModel.setSelected(value, true);
+ GSS.get().onResourceUpdate(value,clearSelection);
+
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching root folder", t);
+ GSS.get().displayError("Unable to fetch root folder");
+ }
+
+ };
+ DeferredCommand.addCommand(gf);
+ }
+ else if(value instanceof OtherUserResource){
+ GetCommand<OtherUserResource> gf = new GetCommand<OtherUserResource>(OtherUserResource.class, value.getUri(), null) {
+
+ @Override
+ public void onComplete() {
+ OtherUserResource rootResource = getResult();
+ ((OtherUserResource)value).setFolders(getResult().getFolders());
+ ((OtherUserResource)value).setFiles(getResult().getFiles());
+
+ if(GSS.get().getTreeView().getSelection().getUri().equals(value.getUri()))
+ selectionModel.setSelected(value, true);
+ GSS.get().onResourceUpdate(value,clearSelection);
+
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching root folder", t);
+ GSS.get().displayError("Unable to fetch root folder");
+ }
+
+ };
+ DeferredCommand.addCommand(gf);
+ }
+
+ }
+
+ }
+ class MyFolderDataProvider extends AsyncDataProvider<RestResource>{
+ private RestResource restResource;
+ private Class resourceClass;
+ public MyFolderDataProvider(RestResource department, Class resourceClass) {
+ super(new ProvidesKey<RestResource>() {
+
+ @Override
+ public Object getKey(RestResource item) {
+ return item.getUri();
+ }});
+ this.restResource = department;
+ this.resourceClass=resourceClass;
+ }
+
+ @Override
+ protected void onRangeChanged(final HasData<RestResource> view) {
+ refresh(null);
+ }
+
+ /**
+ * Retrieve the restResource.
+ *
+ * @return the restResource
+ */
+ public RestResource getRestResource() {
+ return restResource;
+ }
+
+
+ /**
+ * Modify the restResource.
+ *
+ * @param restResource the restResource to set
+ */
+ public void setRestResource(RestResource restResource) {
+ this.restResource = restResource;
+ }
+ List<RestResource> res =null;
+ public void refresh(final RefreshHandler refresh){
+ FolderResource cache = null;
+ if(restResource instanceof RestResourceWrapper && !((RestResourceWrapper)restResource).getResource().isNeedsExpanding())
+ cache = ((RestResourceWrapper)restResource).getResource();
+ GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, restResource.getUri(),cache ) {
+
+ @Override
+ public void onComplete() {
+ if(restResource instanceof RestResourceWrapper){
+ ((RestResourceWrapper)restResource).setResource(getResult());//restResource = getResult();
+ ((RestResourceWrapper)restResource).getResource().setNeedsExpanding(false);
+ }
+ if(usedCachedVersion()&&res!=null){
+
+ updateRowCount(res.size(), true);
+ updateRowData(0,res);
+ return;
+ }
+ String[] folderPaths = null;
+ if(resourceClass.equals(MyFolderResource.class))
+ folderPaths=((MyFolderResource) restResource).getResource().getSubfolderPaths().toArray(new String[] {});
+ else if(resourceClass.equals(SharedFolderResource.class) && restResource instanceof SharedResource)
+ folderPaths=((SharedResource) restResource).getSubfolderPaths().toArray(new String[] {});
+ else if(resourceClass.equals(SharedFolderResource.class)){
+ folderPaths=((SharedFolderResource) restResource).getResource().getSubfolderPaths().toArray(new String[] {});
+ GWT.log("------------>"+folderPaths);
+ }
+ else if(resourceClass.equals(TrashFolderResource.class))
+ folderPaths=((TrashFolderResource) restResource).getResource().getSubfolderPaths().toArray(new String[] {});
+ else if(resourceClass.equals(OthersFolderResource.class) && restResource instanceof OtherUserResource)
+ folderPaths=((OtherUserResource) restResource).getSubfolderPaths().toArray(new String[] {});
+ else if(resourceClass.equals(OthersFolderResource.class))
+ folderPaths=((OthersFolderResource) restResource).getResource().getSubfolderPaths().toArray(new String[] {});
+ MultipleGetCommand.Cached[] cached = null;
+ if(restResource instanceof RestResourceWrapper)
+ cached=((RestResourceWrapper)restResource).getResource().getCache();
+ MultipleGetCommand<FolderResource> gf2 = new MultipleGetCommand<FolderResource>(FolderResource.class,
+ folderPaths, cached) {
+
+ @Override
+ public void onComplete() {
+ res = new ArrayList<RestResource>();
+ for(FolderResource r : getResult()){
+ if(r.isDeleted()){
+
+ }
+ else if(resourceClass.equals(MyFolderResource.class))
+ res.add(new MyFolderResource(r));
+ else if(resourceClass.equals(SharedFolderResource.class)){
+ res.add(new SharedFolderResource(r));
+ }
+ else if(resourceClass.equals(TrashFolderResource.class))
+ res.add(new TrashFolderResource(r));
+ else if(resourceClass.equals(OthersFolderResource.class))
+ res.add(new OthersFolderResource(r));
+ }
+ if(restResource instanceof RestResourceWrapper)
+ ((RestResourceWrapper)restResource).getResource().setFolders(getResult());
+ updateRowCount(res.size(), true);
+ updateRowData(0,res);
+ if(refresh!=null)
+ refresh.onRefresh();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GSS.get().displayError("Unable to fetch subfolders");
+ GWT.log("Unable to fetch subfolders", t);
+ }
+
+ @Override
+ public void onError(String p, Throwable throwable) {
+ GWT.log("Path:"+p, throwable);
+ }
+
+ };
+ DeferredCommand.addCommand(gf2);
+
+ }
+
+ @Override
+ public void onError(Throwable t) {
+
+ GWT.log("Error fetching root folder", t);
+ GSS.get().displayError("Unable to fetch root folder");
+ }
+
+ };
+ DeferredCommand.addCommand(gf);
+ }
+ }
+
+
+ class OthersDataProvider extends AsyncDataProvider<RestResource>{
+ private RestResource restResource;
+ private Class resourceClass;
+ public OthersDataProvider(RestResource department, Class resourceClass) {
+ super(new ProvidesKey<RestResource>() {
+
+ @Override
+ public Object getKey(RestResource item) {
+ return item.getUri();
+ }});
+ this.restResource = department;
+ this.resourceClass=resourceClass;
+ }
+
+ @Override
+ protected void onRangeChanged(final HasData<RestResource> view) {
+ refresh(null);
+ }
+
+ /**
+ * Retrieve the restResource.
+ *
+ * @return the restResource
+ */
+ public RestResource getRestResource() {
+ return restResource;
+ }
+
+
+ /**
+ * Modify the restResource.
+ *
+ * @param restResource the restResource to set
+ */
+ public void setRestResource(RestResource restResource) {
+ this.restResource = restResource;
+ }
+
+ public void refresh(final RefreshHandler refresh){
+ GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
+ restResource.getUri(), null) {
+
+ @Override
+ public void onComplete() {
+ final OthersResource others = getResult();
+ MultipleGetCommand<OtherUserResource> gogo = new MultipleGetCommand<OtherUserResource>(OtherUserResource.class,
+ others.getOthers().toArray(new String[] {}), null) {
+
+ @Override
+ public void onComplete() {
+ List<OtherUserResource> res = getResult();
+ updateRowCount(res.size(), true);
+ List<RestResource> r = new ArrayList<RestResource>();
+ r.addAll(res);
+ updateRowData(0,r);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching Others Root folder", t);
+ GSS.get().displayError("Unable to fetch Others Root folder");
+ }
+
+ @Override
+ public void onError(String p, Throwable throwable) {
+ GWT.log("Path:"+p, throwable);
+ }
+ };
+ DeferredCommand.addCommand(gogo);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Error fetching Others Root folder", t);
+ GSS.get().displayError("Unable to fetch Others Root folder");
+ }
+ };
+ DeferredCommand.addCommand(go);
+ }
+ }
+
+
+
+ /**
+ * Retrieve the rootNodes.
+ *
+ * @return the rootNodes
+ */
+ public ListDataProvider<RestResource> getRootNodes() {
+ return rootNodes;
+ }
+
+
+ /**
+ * Retrieve the mymap.
+ *
+ * @return the mymap
+ */
+ public Map<String, MyFolderDataProvider> getMymap() {
+ return mymap;
+ }
+
+
+ /**
+ * Retrieve the sharedmap.
+ *
+ * @return the sharedmap
+ */
+ public Map<String, MyFolderDataProvider> getSharedmap() {
+ return sharedmap;
+ }
+
+
+ /**
+ * Retrieve the othersmap.
+ *
+ * @return the othersmap
+ */
+ public Map<String, MyFolderDataProvider> getOthersmap() {
+ return othersmap;
+ }
+
+
+
+
+
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.CellTreeView.RefreshHandler;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import com.google.gwt.user.cellview.client.CellTree;
+import com.google.gwt.user.cellview.client.TreeNode;
+
+
+/**
+ * @author kman
+ *
+ */
+public class CellTreeViewUtils {
+ CellTree tree;
+ /**
+ *
+ */
+ public CellTreeViewUtils(CellTree tree) {
+ this.tree = tree;
+ }
+
+ void refreshNodeContainingResource(RestResource r){
+ TreeNode node = tree.getRootTreeNode();
+ refreshNodeContainingResource(node,r);
+ }
+
+ void refreshNodeContainingResource(String uri){
+ TreeNode node = tree.getRootTreeNode();
+ refreshNodeContainingResource(node,uri);
+ }
+
+ private void refreshNodeContainingResource(TreeNode node, RestResource resource){
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+ if(node.getChildValue(i).equals(resource)){
+ if(node.getChildValue(i) instanceof RestResourceWrapper && ((RestResourceWrapper)node.getChildValue(i)).getResource().getFolders().size()==0)
+ return;
+ node.setChildOpen(i, false, true);
+ node.setChildOpen(i, true, true);
+ return;
+ }
+ else if(node.isChildOpen(i)){
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null)
+ refreshNodeContainingResource(n,resource);
+ }
+ }
+
+ }
+
+ void refreshNodeContainingResource(TreeNode node, String uri){
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+ if(node.isChildOpen(i)){
+ if(node.getChildValue(i) instanceof RestResource && ((RestResource)node.getChildValue(i)).getUri().equals(uri)){
+ if(node.getChildValue(i) instanceof RestResourceWrapper && ((RestResourceWrapper)node.getChildValue(i)).getResource().getFolders().size()==0)
+ return;
+ node.setChildOpen(i, false, true);
+ node.setChildOpen(i, true, true);
+ return;
+ }
+ else{
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null)
+ refreshNodeContainingResource(n,uri);
+ }
+ }
+ }
+ }
+ public void openNodeContainingResource(RestResource resource){
+ TreeNode node = tree.getRootTreeNode();
+ openNodeContainingResource(node,resource);
+ }
+ private void openNodeContainingResource(TreeNode node, RestResource resource){
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+
+ if(node.getChildValue(i).equals(resource)){
+ if(node.getChildValue(i) instanceof RestResourceWrapper && ((RestResourceWrapper)node.getChildValue(i)).getResource().getFolders().size()==0)
+ return;
+ node.setChildOpen(i, true, true);
+ return;
+ }
+ else{
+ if(node.isChildOpen(i)){
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null)
+ openNodeContainingResource(n,resource);
+ }
+ }
+
+ }
+ }
+
+ public void openNodeContainingResource(RestResource resource, RefreshHandler handler){
+ TreeNode node = tree.getRootTreeNode();
+ openNodeContainingResource(node,resource,handler);
+ }
+ private void openNodeContainingResource(TreeNode node, RestResource resource, RefreshHandler handler){
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+ if(node.getChildValue(i).equals(resource)){
+ if(node.getChildValue(i) instanceof RestResourceWrapper && ((RestResourceWrapper)node.getChildValue(i)).getResource().getFolders().size()==0)
+ return;
+ //node.setChildOpen(i, false, true);
+ node.setChildOpen(i, true, true);
+ handler.onRefresh();
+ return;
+ }
+ else{
+ if(node.isChildOpen(i)){
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null)
+ openNodeContainingResource(n,resource, handler);
+ }
+ }
+
+ }
+ }
+
+
+
+ public boolean doesNodeContainsResource(TreeNode node, RestResource resource){
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+ if(node.isChildOpen(i)){
+ if(node.getChildValue(i) instanceof RestResource && ((RestResource)node.getChildValue(i)).equals(resource)){
+ return true;
+ }
+ else if(node.isChildOpen(i)){
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null)
+ return doesNodeContainsResource(n,resource);
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean doesNodeContainsResource(TreeNode node, String resource){
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+
+ if(node.getChildValue(i) instanceof RestResource && ((RestResource)node.getChildValue(i)).getUri().equals(resource)){
+ return true;
+ }
+ else if(node.isChildOpen(i)){
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null)
+ return doesNodeContainsResource(n,resource);
+ }
+
+ }
+ return false;
+ }
+
+ public TreeNode getNodeContainingResource(TreeNode node, RestResource resource){
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+
+ if(node.getChildValue(i) instanceof RestResource && ((RestResource)node.getChildValue(i)).getUri().equals(resource.getUri())){
+ return node;
+ }
+ else if(node.isChildOpen(i)){
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null)
+ return getNodeContainingResource(n,resource);
+ }
+
+ }
+ return null;
+ }
+
+ public TreeNode getNodeContainingResource(TreeNode node, String resource){
+ if(node==null)
+ return null;
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+
+ if(node.getChildValue(i) instanceof RestResource && ((RestResource)node.getChildValue(i)).getUri().equals(resource)){
+ return node;
+ }
+ else if(node.isChildOpen(i)){
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null){
+ TreeNode result = getNodeContainingResource2(n,resource);
+ if(result !=null)
+ return result;
+ }
+ }
+
+ }
+ return null;
+ }
+
+ public TreeNode getNodeContainingResource2(TreeNode node, String resource){
+ if(node==null)
+ return null;
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+ if(node.getChildValue(i) instanceof RestResource && ((RestResource)node.getChildValue(i)).getUri().equals(resource)){
+ return node.setChildOpen(i, node.isChildOpen(i));
+ }
+ else if(node.isChildOpen(i)){
+ TreeNode n = node.setChildOpen(i, true);
+ if(n!=null){
+ TreeNode result = getNodeContainingResource2(n,resource);
+ if(result !=null)
+ return result;
+ }
+ }
+
+ }
+ return null;
+ }
+ public boolean doesSharedNodeContainsResource( String resource){
+ if(tree.getRootTreeNode().isChildOpen(2)){
+ TreeNode node = tree.getRootTreeNode().setChildOpen(2, true);
+ return doesNodeContainsResource(node, resource);
+ }
+ return false;
+ }
+
+ public boolean doesSharedNodeContainsResourceIn1stLevel( String resource){
+ if(tree.getRootTreeNode().isChildOpen(2)){
+ TreeNode node = tree.getRootTreeNode().setChildOpen(2, true);
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+
+ if(node.getChildValue(i) instanceof RestResource && ((RestResource)node.getChildValue(i)).getUri().equals(resource)){
+ return true;
+ }
+
+ }
+ return false;
+ }
+ return false;
+ }
+
+ public boolean doesSharedNodeContainsResourceIn2ndLevel( String resource){
+ if(tree.getRootTreeNode().isChildOpen(2)){
+ TreeNode node = tree.getRootTreeNode().setChildOpen(2, true);
+ int count = node.getChildCount();
+ for(int i=0;i<count;i++){
+ if(node.isChildOpen(i)){
+ TreeNode child = node.setChildOpen(i, true);
+ for(int j=0;j<child.getChildCount();j++){
+ if(child.getChildValue(j) instanceof RestResource && ((RestResource)child.getChildValue(j)).getUri().equals(resource)){
+ return true;
+ }
+ }
+ }
+
+
+ }
+ return false;
+ }
+ return false;
+ }
+
+ public boolean doesRootNodeContainsResource( String resource){
+ if(tree.getRootTreeNode().isChildOpen(0)){
+ TreeNode node = tree.getRootTreeNode().setChildOpen(0, true);
+ return doesNodeContainsResource(node, resource);
+ }
+ return false;
+ }
+
+ public boolean doesSharedNodeContainsResource( RestResource resource){
+ if(tree.getRootTreeNode().isChildOpen(2)){
+ TreeNode node = tree.getRootTreeNode().setChildOpen(2, true);
+ return doesNodeContainsResource(node, resource);
+ }
+ return false;
+ }
+
+ public boolean doesRootNodeContainsResource( RestResource resource){
+ if(tree.getRootTreeNode().isChildOpen(0)){
+ TreeNode node = tree.getRootTreeNode().setChildOpen(0, true);
+ return doesNodeContainsResource(node, resource);
+ }
+ return false;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.i18n.client.Constants;
+
+
+/**
+ * This interface contains bindings for the compile-time configurable
+ * entities of the application.
+ *
+ * @author past
+ */
+public interface Configuration extends Constants {
+ /**
+ * @return the name of the service
+ */
+ @DefaultStringValue("GSS")
+ String serviceName();
+
+ /**
+ * @return the login URL
+ */
+ @DefaultStringValue("/gss/login")
+ String loginUrl();
+
+ /**
+ * @return the logout URL
+ */
+ @DefaultStringValue("/gss/login")
+ String logoutUrl();
+
+ /**
+ * @return the authentication cookie name
+ */
+ @DefaultStringValue("_gss_a")
+ String authCookie();
+
+ /**
+ * @return the webdav cookie name
+ */
+ @DefaultStringValue("_gss_wd")
+ String webdavCookie();
+
+ /**
+ * @return the separator string between username and token in the
+ * authentication cookie
+ */
+ @DefaultStringValue("|")
+ String cookieSeparator();
+
+ /**
+ * @return the relative path of the API root URL
+ */
+ @DefaultStringValue("rest/")
+ String apiPath();
+
+ /**
+ * @return the WebDAV URL
+ */
+ @DefaultStringValue("/webdav/")
+ String webdavUrl();
+
+ /**
+ * @return the token TTL note
+ */
+ @DefaultStringValue("")
+ String tokenTTLNote();
+
+ /**
+ * @return the version string
+ */
+ @DefaultStringValue("")
+ String version();
+
+}
--- /dev/null
+serviceName=Pithos
+loginUrl=login
+logoutUrl=/Shibboleth.sso/Logout
+authCookie=_gss_a
+webdavCookie=_gss_wd
+cookieSeparator=|
+apiPath=rest/
+webdavUrl=/webdav/
+tokenTTLNote=The token is valid for 30 days.
+version=1.5
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+
+/**
+ * A dialog for requesting confirmation from the user.
+ *
+ * @author kman
+ */
+public abstract class ConfirmationDialog extends DialogBox {
+
+ /**
+ * The widget's constructor.
+ *
+ * @param message the message to display
+ * @param buttonLabel the label of the confirmation button
+ */
+ public ConfirmationDialog(String message, String buttonLabel) {
+ // Set the dialog's caption.
+ setText("Confirmation");
+ setAnimationEnabled(true);
+ // Create a VerticalPanel to contain the label and the buttons.
+ VerticalPanel outer = new VerticalPanel();
+ HorizontalPanel buttons = new HorizontalPanel();
+
+ HTML text = new HTML("<table><tr><td rowspan='2'> " +
+ AbstractImagePrototype.create(MessagePanel.images.warn()).getHTML() +
+ "</td><td>" + message + "</td></tr></table>");
+ text.setStyleName("gss-warnMessage");
+ outer.add(text);
+
+ // Create the 'Update' button, along with a listener that hides the
+ // dialog when the button is clicked and renames the file.
+ Button ok = new Button(buttonLabel, new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ confirm();
+ hide();
+ }
+ });
+ ok.getElement().setId("confirmation.ok");
+ buttons.add(ok);
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);
+ // Create the 'Cancel' button, along with a listener that hides the
+ // dialog when the button is clicked.
+ Button cancel = new Button("Cancel", new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ cancel();
+ }
+ });
+ cancel.getElement().setId("confirmation.cancel");
+ buttons.add(cancel);
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
+ buttons.setSpacing(8);
+ buttons.setStyleName("gss-warnMessage");
+ outer.setStyleName("gss-warnMessage");
+ outer.add(buttons);
+ outer.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_CENTER);
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
+ setWidget(outer);
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when either
+ // enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ hide();
+ confirm();
+ break;
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ cancel();
+ break;
+ }
+ }
+
+ public abstract void confirm();
+
+ public abstract void cancel();
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.user.client.Window;
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+
+/**
+ * A dialog box that displays the user credentials for use in other client
+ * applications, such as WebDAV clients.
+ *
+ * @author kman
+ */
+public class CredentialsDialog extends DialogBox {
+
+ private final String WIDTH_FIELD = "35em";
+ private final String WIDTH_TEXT = "42em";
+
+ private TextBox passwordBox;
+
+ /**
+ * The 'confirm reset password' dialog box.
+ */
+ private class ConfirmResetPasswordDialog extends DialogBox {
+
+ /**
+ * The widget's constructor.
+ *
+ * @param images the supplied images
+ */
+ private ConfirmResetPasswordDialog(MessagePanel.Images images) {
+ // Set the dialog's caption.
+ setText("Confirmation");
+ setAnimationEnabled(true);
+ // Create a VerticalPanel to contain the label and the buttons.
+ VerticalPanel outer = new VerticalPanel();
+ HorizontalPanel buttons = new HorizontalPanel();
+
+ HTML text;
+ text = new HTML("<table><tr><td>" +
+ AbstractImagePrototype.create(images.warn()).getHTML() +
+ "</td><td>" + "Are you sure you want to create a new " +
+ "WebDAV password?</td></tr></table>");
+ text.setStyleName("gss-warnMessage");
+ outer.add(text);
+
+ // Create the 'Yes' button, along with a listener that hides the
+ // dialog when the button is clicked and resets the password.
+ Button ok = new Button("Yes", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ resetPassword(GSS.get().getCurrentUserResource().getUri());
+ hide();
+ }
+ });
+ buttons.add(ok);
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);
+ // Create the 'No' button, along with a listener that hides the
+ // dialog when the button is clicked.
+ Button cancel = new Button("No", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
+ buttons.add(cancel);
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
+ buttons.setSpacing(8);
+ buttons.setStyleName("gss-warnMessage");
+ outer.setStyleName("gss-warnMessage");
+ outer.add(buttons);
+ outer.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_CENTER);
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
+ setWidget(outer);
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when either
+ // enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ break;
+ }
+ }
+
+ }
+
+ private class ReauthenticateDialog extends DialogBox {
+ /**
+ * The widget constructor.
+ */
+ public ReauthenticateDialog() {
+ // Set the dialog's caption.
+ setText("New Password Created");
+ setAnimationEnabled(true);
+ VerticalPanel outer = new VerticalPanel();
+
+ // Create the text and set a style name so we can style it with CSS.
+ HTML text = new HTML("<p>A new WebDAV password has been created." +
+ "</p><p>You will now be redirected to the initial screen" +
+ " for the changes to take effect. Choose \"Show " +
+ "Credentials\" again afterwards to see the new password.</p>");
+ text.setStyleName("gss-AboutText");
+ outer.add(text);
+
+ // Create the 'OK' button, along with a listener that hides the
+ // dialog when the button is clicked.
+ Button confirm = new Button("Proceed", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ GSS.get().authenticateUser();
+ hide();
+ }
+ });
+ outer.add(confirm);
+ outer.setCellHorizontalAlignment(confirm, HasHorizontalAlignment.ALIGN_CENTER);
+ outer.setSpacing(8);
+ setWidget(outer);
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when
+ // either enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ GSS.get().authenticateUser();
+ hide();
+ break;
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ break;
+ }
+ }
+
+ }
+
+ /**
+ * The widget constructor.
+ */
+ public CredentialsDialog(final MessagePanel.Images images) {
+ // Set the dialog's caption.
+ setText("User Credentials");
+ setAnimationEnabled(true);
+ // A VerticalPanel that contains the 'about' label and the 'OK' button.
+ VerticalPanel outer = new VerticalPanel();
+ Configuration conf = (Configuration) GWT.create(Configuration.class);
+ String service = conf.serviceName();
+ String path = Window.Location.getPath();
+ String baseUrl = GWT.getModuleBaseURL();
+ String homeUrl = baseUrl.substring(0, baseUrl.indexOf(path));
+ String webdavUrl = homeUrl + conf.webdavUrl();
+ String tokenNote = conf.tokenTTLNote();
+ // Create the text and set a style name so we can style it with CSS.
+ HTML text = new HTML("<p>These are the user credentials that are " +
+ "required for interacting with " + service + ". You can copy" +
+ " and paste the username and password in the WebDAV client " +
+ "in order to use " + service + " through the WebDAV " +
+ "interface, at:<br/> " + webdavUrl + "<br/>" + tokenNote +
+ "</p>");
+ text.setStyleName("gss-AboutText");
+ text.setWidth(WIDTH_TEXT);
+ outer.add(text);
+ FlexTable table = new FlexTable();
+ table.setText(0, 0, "Username");
+ table.setText(1, 0, "Password");
+ table.setText(2, 0, "Token");
+ TextBox username = new TextBox();
+ final GSS app = GSS.get();
+ username.setText(app.getCurrentUserResource().getUsername());
+ username.setReadOnly(true);
+ username.setWidth(WIDTH_FIELD);
+ username.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ GSS.enableIESelection();
+ ((TextBox) event.getSource()).selectAll();
+ GSS.preventIESelection();
+ }
+
+ });
+ table.setWidget(0, 1, username);
+ passwordBox = new TextBox();
+ passwordBox.setText(app.getWebDAVPassword());
+ passwordBox.setReadOnly(true);
+ passwordBox.setWidth(WIDTH_FIELD);
+ passwordBox.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ GSS.enableIESelection();
+ ((TextBox) event.getSource()).selectAll();
+ GSS.preventIESelection();
+ }
+
+ });
+ table.setWidget(1, 1, passwordBox);
+
+ TextBox tokenBox = new TextBox();
+ tokenBox.setText(app.getToken());
+ tokenBox.setReadOnly(true);
+ tokenBox.setWidth(WIDTH_FIELD);
+ tokenBox.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ GSS.enableIESelection();
+ ((TextBox) event.getSource()).selectAll();
+ GSS.preventIESelection();
+ }
+
+ });
+ table.setWidget(2, 1, tokenBox);
+
+ table.getFlexCellFormatter().setStyleName(0, 0, "props-labels");
+ table.getFlexCellFormatter().setStyleName(0, 1, "props-values");
+ table.getFlexCellFormatter().setStyleName(1, 0, "props-labels");
+ table.getFlexCellFormatter().setStyleName(1, 1, "props-values");
+ table.getFlexCellFormatter().setStyleName(2, 0, "props-labels");
+ table.getFlexCellFormatter().setStyleName(2, 1, "props-values");
+ outer.add(table);
+
+ // Create the 'OK' button, along with a listener that hides the dialog
+ // when the button is clicked.
+ Button confirm = new Button("Close", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
+ outer.add(confirm);
+ outer.setCellHorizontalAlignment(confirm, HasHorizontalAlignment.ALIGN_CENTER);
+
+ // Create the 'Reset password' button, along with a listener that hides
+ // the dialog when the button is clicked.
+ Button resetPassword = new Button("Reset Password", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ ConfirmResetPasswordDialog dlg = new ConfirmResetPasswordDialog(images);
+ dlg.center();
+ }
+ });
+ outer.add(resetPassword);
+ outer.setCellHorizontalAlignment(resetPassword, HasHorizontalAlignment.ALIGN_CENTER);
+
+ outer.setSpacing(8);
+ setWidget(outer);
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when
+ // either enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ break;
+ }
+ }
+
+
+ /**
+ * Generate an RPC request to reset WebDAV password.
+ *
+ * @param userId the Uri of the user whose password will be reset
+ */
+ private void resetPassword(String userUri) {
+
+ if (userUri == null || userUri.length() == 0) {
+ GSS.get().displayError("Empty user Uri!");
+ return;
+ }
+ GWT.log("resetPassword(" + userUri + ")", null);
+ PostCommand cg = new PostCommand(userUri + "?resetWebDAV", "", 200) {
+
+ @Override
+ public void onComplete() {
+ ReauthenticateDialog dlg = new ReauthenticateDialog();
+ dlg.center();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary" +
+ " permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("Resource does not exist");
+ else
+ GSS.get().displayError("Unable to reset password:" +
+ ((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error resetting password:" +
+ t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cg);
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.MessagePanel.Images;\r
+import org.gss_project.gss.web.client.rest.DeleteCommand;\r
+import org.gss_project.gss.web.client.rest.MultipleDeleteCommand;\r
+import org.gss_project.gss.web.client.rest.RestException;\r
+import org.gss_project.gss.web.client.rest.resource.FileResource;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.user.client.DeferredCommand;\r
+import com.google.gwt.user.client.Event.NativePreviewEvent;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.DialogBox;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'delete file' dialog box.\r
+ */\r
+public class DeleteFileDialog extends DialogBox {\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ *\r
+ * @param images the supplied images\r
+ */\r
+ public DeleteFileDialog(Images images) {\r
+ // Set the dialog's caption.\r
+ setText("Confirmation");\r
+ setAnimationEnabled(true);\r
+ Object selection = GSS.get().getCurrentSelection();\r
+ // Create a VerticalPanel to contain the label and the buttons.\r
+ VerticalPanel outer = new VerticalPanel();\r
+ HorizontalPanel buttons = new HorizontalPanel();\r
+\r
+ HTML text;\r
+ if (selection instanceof FileResource)\r
+ text = new HTML("<table><tr><td>" + AbstractImagePrototype.create(images.warn()).getHTML() + "</td><td>" + "Are you sure you want to <b>permanently</b> delete file '" + ((FileResource) selection).getName() + "'?</td></tr></table>");\r
+ else\r
+ text = new HTML("<table><tr><td>" + AbstractImagePrototype.create(images.warn()).getHTML() + "</td><td>" + "Are you sure you want to <b>permanently</b> delete the selected files?</td></tr></table>");\r
+ text.setStyleName("gss-warnMessage");\r
+ outer.add(text);\r
+\r
+ // Create the 'Delete' button, along with a listener that hides the dialog\r
+ // when the button is clicked and deletes the file.\r
+ Button ok = new Button("Delete", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ deleteFile();\r
+ hide();\r
+ }\r
+ });\r
+ ok.getElement().setId("confirmation.ok");\r
+ buttons.add(ok);\r
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
+ // Create the 'Cancel' button, along with a listener that hides the\r
+ // dialog when the button is clicked.\r
+ Button cancel = new Button("Cancel", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ hide();\r
+ }\r
+ });\r
+ cancel.getElement().setId("confirmation.cancel");\r
+ buttons.add(cancel);\r
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ buttons.setSpacing(8);\r
+ buttons.setStyleName("gss-warnMessage");\r
+ outer.setStyleName("gss-warnMessage");\r
+ outer.add(buttons);\r
+ outer.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_CENTER);\r
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
+ setWidget(outer);\r
+ }\r
+\r
+ /**\r
+ * Generate an RPC request to delete a file.\r
+ *\r
+ * @param userId the ID of the current user\r
+ */\r
+ private void deleteFile() {\r
+ Object selection = GSS.get().getCurrentSelection();\r
+ if (selection == null) {\r
+ GSS.get().displayError("No file was selected");\r
+ return;\r
+ }\r
+ if (selection instanceof FileResource) {\r
+ FileResource file = (FileResource) selection;\r
+\r
+ DeleteCommand df = new DeleteCommand(file.getUri()){\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());\r
+ GSS.get().getStatusPanel().updateStats();\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ if(t instanceof RestException){\r
+ int statusCode = ((RestException)t).getHttpStatusCode();\r
+ if(statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions");\r
+ else if(statusCode == 404)\r
+ GSS.get().displayError("File not found");\r
+ else\r
+ GSS.get().displayError("Unable to delete file: "+((RestException)t).getHttpStatusText());\r
+ }\r
+ else\r
+ GSS.get().displayError("System error unable to delete file: "+t.getMessage());\r
+ }\r
+ };\r
+\r
+ DeferredCommand.addCommand(df);\r
+ }\r
+ else if(selection instanceof List){\r
+ List<FileResource> files = (List<FileResource>) selection;\r
+ List<String> fileIds = new ArrayList<String>();\r
+ for(FileResource f : files)\r
+ fileIds.add(f.getUri());\r
+\r
+ MultipleDeleteCommand ed = new MultipleDeleteCommand(fileIds.toArray(new String[0])){\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());\r
+ }\r
+\r
+ @Override\r
+ public void onError(String path, Throwable t) {\r
+ GWT.log("", t);\r
+ if(t instanceof RestException){\r
+ int statusCode = ((RestException)t).getHttpStatusCode();\r
+ if(statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions");\r
+ else if(statusCode == 404)\r
+ GSS.get().displayError("File not found");\r
+ else\r
+ GSS.get().displayError("Unable to delete file:"+((RestException)t).getHttpStatusText());\r
+ }\r
+ else\r
+ GSS.get().displayError("System error unable to delete file:"+t.getMessage());\r
+\r
+ }\r
+ };\r
+\r
+ DeferredCommand.addCommand(ed);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
+ super.onPreviewNativeEvent(preview);\r
+\r
+ NativeEvent evt = preview.getNativeEvent();\r
+ if (evt.getType().equals("keydown"))\r
+ // Use the popup's key preview hooks to close the dialog when either\r
+ // enter or escape is pressed.\r
+ switch (evt.getKeyCode()) {\r
+ case KeyCodes.KEY_ENTER:\r
+ hide();\r
+ deleteFile();\r
+ break;\r
+ case KeyCodes.KEY_ESCAPE:\r
+ hide();\r
+ break;\r
+ }\r
+ }\r
+\r
+\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.MessagePanel.Images;\r
+import org.gss_project.gss.web.client.rest.DeleteCommand;\r
+import org.gss_project.gss.web.client.rest.RestException;\r
+import org.gss_project.gss.web.client.rest.resource.FolderResource;\r
+import org.gss_project.gss.web.client.rest.resource.RestResource;\r
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;\r
+import org.gss_project.gss.web.client.rest.resource.TrashFolderResource;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.user.client.DeferredCommand;\r
+import com.google.gwt.user.client.Event.NativePreviewEvent;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.DialogBox;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'delete folder' dialog box.\r
+ */\r
+public class DeleteFolderDialog extends DialogBox {\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ * @param images the supplied images\r
+ */\r
+ public DeleteFolderDialog(Images images) {\r
+ // Set the dialog's caption.\r
+ setText("Confirmation");\r
+ setAnimationEnabled(true);\r
+ FolderResource folder = ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource();\r
+ // Create a VerticalPanel to contain the HTML label and the buttons.\r
+ VerticalPanel outer = new VerticalPanel();\r
+ HorizontalPanel buttons = new HorizontalPanel();\r
+\r
+ HTML text = new HTML("<table><tr><td rowspan='2'>" + AbstractImagePrototype.create(images.warn()).getHTML() +\r
+ "</td><td>" + "Are you sure you want to <b>permanently</b> delete folder '" + folder.getName() +\r
+ "'?</td></tr></table>");\r
+ text.setStyleName("gss-warnMessage");\r
+ outer.add(text);\r
+\r
+ // Create the 'Delete' button, along with a listener that hides the dialog\r
+ // when the button is clicked and deletes the folder.\r
+ Button ok = new Button("Delete", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ deleteFolder();\r
+ hide();\r
+ }\r
+ });\r
+ ok.getElement().setId("confirmation.ok");\r
+ buttons.add(ok);\r
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
+ // Create the 'Cancel' button, along with a listener that hides the\r
+ // dialog when the button is clicked.\r
+ Button cancel = new Button("Cancel", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ hide();\r
+ }\r
+ });\r
+ cancel.getElement().setId("confirmation.cancel");\r
+ buttons.add(cancel);\r
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ buttons.setSpacing(8);\r
+ buttons.setStyleName("gss-warnMessage");\r
+ outer.setStyleName("gss-warnMessage");\r
+ outer.add(buttons);\r
+ outer.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_CENTER);\r
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
+ setWidget(outer);\r
+ }\r
+\r
+ /**\r
+ * Generate an RPC request to delete a folder.\r
+ *\r
+ * @param userId the ID of the current user\r
+ */\r
+ private void deleteFolder() {\r
+ RestResource folder = GSS.get().getTreeView().getSelection();\r
+ if (folder == null) {\r
+ GSS.get().displayError("No folder was selected");\r
+ return;\r
+ }\r
+ if(!(folder instanceof RestResourceWrapper))\r
+ return;\r
+\r
+ DeleteCommand df = new DeleteCommand(folder.getUri()){\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ FolderResource fres = ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource();\r
+ if((RestResourceWrapper) GSS.get().getTreeView().getSelection() instanceof TrashFolderResource)\r
+ GSS.get().getTreeView().updateTrashNode();\r
+ else\r
+ GSS.get().getTreeView().updateNodeChildrenForRemove(fres.getParentURI());\r
+ GSS.get().getTreeView().clearSelection();\r
+ GSS.get().showFileList(true);\r
+ \r
+ GSS.get().getStatusPanel().updateStats();\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ if(t instanceof RestException){\r
+ int statusCode = ((RestException)t).getHttpStatusCode();\r
+ if(statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions");\r
+ else if(statusCode == 404)\r
+ GSS.get().displayError("Folder not found");\r
+ else\r
+ GSS.get().displayError("Unable to delete folder: "+((RestException)t).getHttpStatusText());\r
+ }\r
+ else\r
+ GSS.get().displayError("System error unable to delete folder: "+t.getMessage());\r
+ }\r
+ };\r
+\r
+ DeferredCommand.addCommand(df);\r
+ }\r
+\r
+ @Override\r
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
+ super.onPreviewNativeEvent(preview);\r
+\r
+ NativeEvent evt = preview.getNativeEvent();\r
+ if (evt.getType().equals("keydown"))\r
+ // Use the popup's key preview hooks to close the dialog when either\r
+ // enter or escape is pressed.\r
+ switch (evt.getKeyCode()) {\r
+ case KeyCodes.KEY_ENTER:\r
+ hide();\r
+ deleteFolder();\r
+ break;\r
+ case KeyCodes.KEY_ESCAPE:\r
+ hide();\r
+ break;\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.MessagePanel.Images;\r
+import org.gss_project.gss.web.client.rest.DeleteCommand;\r
+import org.gss_project.gss.web.client.rest.RestException;\r
+import org.gss_project.gss.web.client.rest.resource.GroupResource;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.user.client.DeferredCommand;\r
+import com.google.gwt.user.client.Event.NativePreviewEvent;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.DialogBox;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.TreeItem;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'delete group' dialog box.\r
+ */\r
+public class DeleteGroupDialog extends DialogBox {\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ * @param images the supplied images\r
+ */\r
+ public DeleteGroupDialog(final Images images) {\r
+ // Use this opportunity to set the dialog's caption.\r
+ setText("Delete group");\r
+ setAnimationEnabled(true);\r
+ final GroupResource group = (GroupResource) GSS.get().getCurrentSelection();\r
+ // Create a VerticalPanel to contain the 'about' label and the 'OK'\r
+ // button.\r
+ final VerticalPanel outer = new VerticalPanel();\r
+ final HorizontalPanel buttons = new HorizontalPanel();\r
+\r
+ // Create the 'about' text and set a style name so we can style it with\r
+ // CSS.\r
+ final HTML text = new HTML("<table><tr><td>" + AbstractImagePrototype.create(images.warn()).getHTML() + "</td><td>" + "Are you sure you want to delete group '" + group.getName() + "'?</td></tr></table>");\r
+ text.setStyleName("gss-warnMessage");\r
+ outer.add(text);\r
+\r
+ // Create the 'Quit' button, along with a listener that hides the dialog\r
+ // when the button is clicked and quits the application.\r
+ final Button ok = new Button("OK", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ deleteGroup();\r
+ hide();\r
+ }\r
+ });\r
+ ok.getElement().setId("deleteGroup.button.ok");\r
+ buttons.add(ok);\r
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
+ // Create the 'Cancel' button, along with a listener that hides the\r
+ // dialog\r
+ // when the button is clicked.\r
+ final Button cancel = new Button("Cancel", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ hide();\r
+ }\r
+ });\r
+ cancel.getElement().setId("deleteGroup.button.cancel");\r
+ buttons.add(cancel);\r
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ buttons.setSpacing(8);\r
+ buttons.setStyleName("gss-warnMessage");\r
+ outer.setStyleName("gss-warnMessage");\r
+ outer.add(buttons);\r
+ outer.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_CENTER);\r
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
+ setWidget(outer);\r
+ }\r
+\r
+ /**\r
+ * Generate an RPC request to delete a group.\r
+ *\r
+ * @param userId the ID of the current user\r
+ */\r
+ private void deleteGroup() {\r
+ final TreeItem group = GSS.get().getGroups().getCurrent();\r
+ if (group == null) {\r
+ GSS.get().displayError("No group was selected!");\r
+ return;\r
+ }\r
+ DeleteCommand dg = new DeleteCommand(((GroupResource)group.getUserObject()).getUri()){\r
+ @Override\r
+ public void onComplete() {\r
+ GSS.get().getGroups().updateGroups();\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ if(t instanceof RestException){\r
+ int statusCode = ((RestException)t).getHttpStatusCode();\r
+ if(statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions");\r
+ else if(statusCode == 404)\r
+ GSS.get().displayError("Group not found");\r
+ else\r
+ GSS.get().displayError("Unable to delete group:"+((RestException)t).getHttpStatusText());\r
+ }\r
+ else\r
+ GSS.get().displayError("System error unable to delete group:"+t.getMessage());\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(dg);\r
+ }\r
+\r
+\r
+ @Override\r
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
+ super.onPreviewNativeEvent(preview);\r
+\r
+ NativeEvent evt = preview.getNativeEvent();\r
+ if (evt.getType().equals("keydown"))\r
+ // Use the popup's key preview hooks to close the dialog when either\r
+ // enter or escape is pressed.\r
+ switch (evt.getKeyCode()) {\r
+ case KeyCodes.KEY_ENTER:\r
+ hide();\r
+ deleteGroup();\r
+ break;\r
+ case KeyCodes.KEY_ESCAPE:\r
+ hide();\r
+ break;\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.MessagePanel.Images;
+import org.gss_project.gss.web.client.rest.DeleteCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.TreeItem;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class DeleteUserDialog extends DialogBox {
+
+ /**
+ * The widget's constructor.
+ * @param images the supplied images
+ */
+ public DeleteUserDialog(final Images images) {
+ // Use this opportunity to set the dialog's caption.
+ setText("Delete user");
+ setAnimationEnabled(true);
+ final GroupUserResource group = (GroupUserResource) GSS.get().getCurrentSelection();
+ // Create a VerticalPanel to contain the 'about' label and the 'OK'
+ // button.
+ final VerticalPanel outer = new VerticalPanel();
+ final HorizontalPanel buttons = new HorizontalPanel();
+
+ // Create the 'about' text and set a style name so we can style it with
+ // CSS.
+ final HTML text = new HTML("<table><tr><td>" + AbstractImagePrototype.create(images.warn()).getHTML() + "</td><td>" + "Are you sure you want to remove user '" + group.getName() + "'?</td></tr></table>");
+ text.setStyleName("gss-warnMessage");
+ outer.add(text);
+
+ // Create the 'Quit' button, along with a listener that hides the dialog
+ // when the button is clicked and quits the application.
+ final Button ok = new Button("OK", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ deleteUser();
+ hide();
+ }
+ });
+ ok.getElement().setId("deleteUser.button.ok");
+ buttons.add(ok);
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);
+ // Create the 'Cancel' button, along with a listener that hides the
+ // dialog
+ // when the button is clicked.
+ final Button cancel = new Button("Cancel", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
+ cancel.getElement().setId("confirmation.button.cancel");
+ buttons.add(cancel);
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
+ buttons.setSpacing(8);
+ buttons.setStyleName("gss-warnMessage");
+ outer.setStyleName("gss-warnMessage");
+ outer.add(buttons);
+ outer.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_CENTER);
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
+ setWidget(outer);
+ }
+
+ /**
+ * Generate an RPC request to delete a group.
+ *
+ * @param userId the ID of the current user
+ */
+ private void deleteUser() {
+ final TreeItem user = GSS.get().getGroups().getCurrent();
+ final TreeItem group = user.getParentItem();
+ if (group == null) {
+ GSS.get().displayError("No user was selected!");
+ return;
+ }
+ final GroupUserResource memberR = (GroupUserResource) user.getUserObject();
+ DeleteCommand du = new DeleteCommand(memberR.getUri()){
+
+ @Override
+ public void onComplete() {
+ GSS.get().getGroups().updateGroups();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("User not found");
+ else
+ GSS.get().displayError("Unable to delete user:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error unable to delete user:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(du);
+
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when either
+ // enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ hide();
+ deleteUser();
+ break;
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ break;
+ }
+ }
+
+}
+
--- /dev/null
+/*
+ * Copyright 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import java.util.List;
+
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.ListBox;
+
+
+/**
+ * A helper class with static methods that manipulate display
+ * widgets in various useful ways, not available in GWT.
+ *
+ * @author past
+ */
+public class DisplayHelper {
+
+ /**
+ * A flag that denotes that no selection should be made while
+ * displaying the rows of a table.
+ */
+ public static final int NO_SELECTION = -1;
+
+ /**
+ * Clear any current selection in the specified ListBox.
+ */
+ public static void clearSelections(ListBox listBox) {
+ for (int i=0; i<listBox.getItemCount(); i++)
+ if (listBox.isItemSelected(i))
+ listBox.setItemSelected(i, false);
+ }
+
+ /**
+ * Select the item in the listBox whose value matches the provided
+ * value.
+ */
+ public static void selectMatch(ListBox listBox, String value) {
+ for (int i=0; i<listBox.getItemCount(); i++)
+ if (listBox.getValue(i).equals(value))
+ listBox.setItemSelected(i, true);
+ else
+ listBox.setItemSelected(i, false);
+ }
+
+ /**
+ * Select the items in the listBox whose value matches the provided
+ * value list. Every value that is matched in the listBox is removed
+ * from the value list, in order to let the caller know what values
+ * were not matched. Therefore the caller must be prepared for the
+ * value list to be modified.
+ *
+ * @param listBox the ListBox
+ * @param values the list of values to be selected
+ */
+ public static void selectMultiMatch(ListBox listBox, List values) {
+ for (int i=0; i<listBox.getItemCount(); i++)
+ if (values.contains(listBox.getValue(i))) {
+ listBox.setItemSelected(i, true);
+ values.remove(listBox.getValue(i));
+ } else
+ listBox.setItemSelected(i, false);
+ }
+
+ public static native void log(String message) /*-{
+ var logger = $wnd.console;
+ if (logger && logger.debug)
+ logger.debug(message);
+ else if (logger && logger.log)
+ logger.log(message);
+ }-*/;
+
+ /**
+ * Make the specified row look like selected or not, according to the
+ * <code>selected</code> flag.
+ *
+ * @param row the row number in the list of entries (i.e. ignoring the header line)
+ * @param selected the flag that denotes whether the <code>styleName</code> should
+ * be added or removed
+ * @param styleName the name of the CSS style
+ */
+ public static void styleRow(final FlexTable table, final int row, final boolean selected, String styleName) {
+ if (row != -1)
+ if (selected)
+ table.getRowFormatter().addStyleName(row + 1, styleName);
+ else
+ table.getRowFormatter().removeStyleName(row + 1, styleName);
+ }
+
+ /**
+ * Select the specified row in the table. This entails modifying its style
+ * as well as the style of the previously selected row.
+ *
+ * @param table the FlexTable widget
+ * @param row the newly selected row
+ * @param previousRow the previously selected row
+ * @param styleName the name of the CSS style
+ * @return the newly selected row
+ */
+ public static int selectRow(final FlexTable table, final int row, final int previousRow, String styleName) {
+ // Reset the style of the previously selected row.
+ styleRow(table, previousRow, false, styleName);
+ // Select the row that was clicked.
+ styleRow(table, row, true, styleName);
+ return row;
+ }
+ /**
+ * The implementation of this trim method also checks for
+ * no brake space characters (nbsp) = '\00A0'
+ * and removes them
+ *
+ * @param input
+ * @return the new trimmed string without whitespace or no brake space
+ */
+ public static native String trim(String input) /*-{
+ if(input.length == 0)
+ return input;
+ if((input[0]||input[input.length-1]) != '\u0020' && (input[0]||input[input.length-1]) != '\u00A0')
+ return input;
+ var r1 = input.replace(/^(\s*)/, '');
+ var r2 = r1.replace(/\s*$/, '');
+ return r2;
+ }-*/;
+
+}
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import org.gss_project.gss.web.client.rest.MultiplePostCommand;
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * @author kman
+ */
+public class DnDFolderPopupMenu extends PopupPanel {
+
+ public DnDFolderPopupMenu(final CellTreeView.Images newImages, final FolderResource target, final Object toCopy) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(true);
+ setAnimationEnabled(true);
+ // A dummy command that we will execute from unimplemented leaves.
+ final Command cancelCmd = new Command() {
+
+ @Override
+ public void execute() {
+ hide();
+ }
+ };
+
+ final MenuBar contextMenu = new MenuBar(true);
+ final CellTreeView folders = GSS.get().getTreeView();
+
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.cut()).getHTML() + " Move</span>", true, new Command() {
+
+ @Override
+ public void execute() {
+ if (toCopy instanceof RestResourceWrapper){
+ moveFolder(target, ((RestResourceWrapper) toCopy).getResource());
+ }
+ else if(toCopy instanceof List){
+ List<FileResource> files = GSS.get().getFileList().getSelectedFiles();
+ moveFiles(target, files);
+ }
+ hide();
+ }
+
+ }).setVisible(target != null);
+
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy</span>", true, new Command() {
+
+ @Override
+ public void execute() {
+ if (toCopy instanceof RestResourceWrapper)
+ copyFolder(target, ((RestResourceWrapper) toCopy).getResource());
+ else if(toCopy instanceof List){
+ List<FileResource> files = GSS.get().getFileList().getSelectedFiles();
+ copyFiles(target, files);
+ }
+ hide();
+ }
+
+ }).setVisible(target != null);
+
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.trash()).getHTML() + " Delete (Trash)</span>", true, new Command() {
+
+ @Override
+ public void execute() {
+ GWT.log("EXECUTE TRASH:"+toCopy.getClass().getName());
+ if (toCopy instanceof RestResourceWrapper){
+ trashFolder(((RestResourceWrapper) toCopy).getResource());
+ }
+ else if(toCopy instanceof List){
+ List<FileResource> files = GSS.get().getFileList().getSelectedFiles();
+ trashFiles(files);
+ }
+ hide();
+ }
+
+ }).setVisible(target == null);
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Cancel</span>", true, cancelCmd);
+
+ add(contextMenu);
+
+ }
+
+ private void copyFolder(final FolderResource target, FolderResource toCopy) {
+ String atarget = target.getUri();
+ atarget = atarget.endsWith("/") ? atarget : atarget + '/';
+ atarget = atarget + toCopy.getName();
+ PostCommand cf = new PostCommand(toCopy.getUri() + "?copy=" + atarget, "", 200) {
+
+ @Override
+ public void onComplete() {
+ GSS.get().getTreeView().updateNodeChildren(new RestResourceWrapper(target));
+ GSS.get().getStatusPanel().updateStats();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if (t instanceof RestException) {
+ int statusCode = ((RestException) t).getHttpStatusCode();
+ if (statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+
+ else if (statusCode == 409)
+ GSS.get().displayError("A folder with the same name already exists");
+ else if (statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to copy folder:" + ((RestException)t).getHttpStatusText());
+ } else
+ GSS.get().displayError("System error copying folder:" + t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cf);
+ }
+
+ private void moveFolder(final FolderResource target, final FolderResource toCopy) {
+ String atarget = target.getUri();
+ atarget = atarget.endsWith("/") ? atarget : atarget + '/';
+ atarget = atarget + toCopy.getName();
+
+ PostCommand cf = new PostCommand(toCopy.getUri() + "?move=" + atarget, "", 200) {
+
+ @Override
+ public void onComplete() {
+ GWT.log("[MOVE]"+target.getUri()+" "+ toCopy.getParentURI());
+ GSS.get().getTreeView().updateNodeChildren(new RestResourceWrapper(target));
+ GSS.get().getTreeView().updateNodeChildrenForRemove(toCopy.getParentURI());
+ GSS.get().getStatusPanel().updateStats();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if (t instanceof RestException) {
+ int statusCode = ((RestException) t).getHttpStatusCode();
+ if (statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+
+ else if (statusCode == 409)
+ GSS.get().displayError("A folder with the same name already exists");
+ else if (statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to copy folder:" + ((RestException)t).getHttpStatusText());
+ } else
+ GSS.get().displayError("System error copying folder:" + t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cf);
+ }
+
+ private void copyFiles(final FolderResource ftarget, List<FileResource> files) {
+ List<String> fileIds = new ArrayList<String>();
+ String target = ftarget.getUri();
+ target = target.endsWith("/") ? target : target + '/';
+ for (FileResource fileResource : files) {
+ String fileTarget = target + URL.encodeComponent(fileResource.getName());
+ fileIds.add(fileResource.getUri() + "?copy=" + fileTarget);
+ }
+ int index = 0;
+ executeCopyOrMoveFiles(index, fileIds);
+
+ }
+
+ private void moveFiles(final FolderResource ftarget, List<FileResource> files) {
+ List<String> fileIds = new ArrayList<String>();
+ String target = ftarget.getUri();
+ target = target.endsWith("/") ? target : target + '/';
+ for (FileResource fileResource : files) {
+ String fileTarget = target + URL.encodeComponent(fileResource.getName());
+ fileIds.add(fileResource.getUri() + "?move=" + fileTarget);
+ }
+ int index = 0;
+ executeCopyOrMoveFiles(index, fileIds);
+
+ }
+
+ private void trashFolder(final FolderResource folder){
+ PostCommand tot = new PostCommand(folder.getUri()+"?trash=","",200){
+
+ @Override
+ public void onComplete() {
+ GSS.get().getTreeView().updateNodeChildrenForRemove(folder.getParentURI());
+ GSS.get().getTreeView().updateTrashNode();
+ /*for(TreeItem item : items)
+ GSS.get().getFolders().updateFolder((DnDTreeItem) item);
+ GSS.get().getFolders().update(GSS.get().getFolders().getTrashItem());
+
+ GSS.get().showFileList(true);
+ */
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("Folder does not exist");
+ else
+ GSS.get().displayError("Unable to trash folder:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error trashing folder:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(tot);
+ }
+
+ private void trashFiles(List<FileResource> files){
+ final List<String> fileIds = new ArrayList<String>();
+ for(FileResource f : files)
+ fileIds.add(f.getUri()+"?trash=");
+ MultiplePostCommand tot = new MultiplePostCommand(fileIds.toArray(new String[0]),200){
+
+ @Override
+ public void onComplete() {
+ GSS.get().showFileList(true);
+ }
+
+ @Override
+ public void onError(String p, Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("File does not exist");
+ else
+ GSS.get().displayError("Unable to trash file:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error trashing file:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(tot);
+ }
+
+
+ private void executeCopyOrMoveFiles(final int index, final List<String> paths) {
+ if (index >= paths.size()) {
+ GSS.get().showFileList(true);
+ GSS.get().getStatusPanel().updateStats();
+ return;
+ }
+ PostCommand cf = new PostCommand(paths.get(index), "", 200) {
+
+ @Override
+ public void onComplete() {
+ executeCopyOrMoveFiles(index + 1, paths);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if (t instanceof RestException) {
+ int statusCode = ((RestException) t).getHttpStatusCode();
+ if (statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if (statusCode == 404)
+ GSS.get().displayError("File not found");
+ else if (statusCode == 409)
+ GSS.get().displayError("A file with the same name already exists");
+ else if (statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to copy file:" + ((RestException)t).getHttpStatusText());
+ } else
+ GSS.get().displayError("System error copying file:" + t.getMessage());
+
+ }
+ };
+ DeferredCommand.addCommand(cf);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.commands.CopyCommand;
+import org.gss_project.gss.web.client.commands.CutCommand;
+import org.gss_project.gss.web.client.commands.DeleteCommand;
+import org.gss_project.gss.web.client.commands.PasteCommand;
+import org.gss_project.gss.web.client.commands.ToTrashCommand;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.List;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * The 'Edit' menu implementation.
+ */
+public class EditMenu extends PopupPanel implements ClickHandler {
+
+ /**
+ * The widget's images.
+ */
+ private final Images images;
+
+ private final MenuBar contextMenu = new MenuBar(true);
+
+ /**
+ * An image bundle for this widget's images.
+ */
+ public interface Images extends ClientBundle, FileMenu.Images, MessagePanel.Images {
+
+ /**
+ * Will bundle the file 'editcut.png' residing in the package
+ * 'org.gss_project.gss.web.resources'.
+ *
+ * @return the image prototype
+ */
+ @Source("org/gss_project/gss/resources/editcut.png")
+ ImageResource cut();
+
+ /**
+ * Will bundle the file 'editcopy.png' residing in the package
+ * 'org.gss_project.gss.web.resources'.
+ *
+ * @return the image prototype
+ */
+ @Source("org/gss_project/gss/resources/editcopy.png")
+ ImageResource copy();
+
+ /**
+ * Will bundle the file 'editpaste.png' residing in the package
+ * 'org.gss_project.gss.web.resources'.
+ *
+ * @return the image prototype
+ */
+ @Source("org/gss_project/gss/resources/editpaste.png")
+ ImageResource paste();
+
+ /**
+ * Will bundle the file 'editdelete.png' residing in the package
+ * 'org.gss_project.gss.web.resources'.
+ *
+ * @return the image prototype
+ */
+ @Override
+ @Source("org/gss_project/gss/resources/editdelete.png")
+ ImageResource delete();
+
+ /**
+ * Will bundle the file 'translate.png' residing in the package
+ * 'org.gss_project.gss.web.resources'.
+ *
+ * @return the image prototype
+ */
+ @Source("org/gss_project/gss/resources/translate.png")
+ ImageResource selectAll();
+
+ /**
+ * Will bundle the file 'border_remove.png' residing in the package
+ * 'org.gss_project.gss.web.resources'.
+ *
+ * @return the image prototype
+ */
+ @Source("org/gss_project/gss/resources/border_remove.png")
+ ImageResource unselectAll();
+ }
+
+ /**
+ * The widget's constructor.
+ *
+ * @param newImages the image bundle passed on by the parent object
+ */
+ public EditMenu(final Images newImages) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(true);
+ setAnimationEnabled(true);
+ images = newImages;
+ createMenu();
+ add(contextMenu);
+ }
+
+ @Override
+ public void onClick(ClickEvent event) {
+ final EditMenu menu = new EditMenu(images);
+ final int left = event.getRelativeElement().getAbsoluteLeft();
+ final int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight();
+ menu.setPopupPosition(left, top);
+ menu.show();
+ }
+
+ public MenuBar createMenu() {
+ contextMenu.clearItems();
+ contextMenu.setAutoOpen(false);
+
+ final Command selectAllCommand = new Command() {
+
+ @Override
+ public void execute() {
+ hide();
+ if(GSS.get().isFileListShowing())
+ GSS.get().getFileList().selectAllRows();
+ else if(GSS.get().isSearchResultsShowing())
+ GSS.get().getSearchResults().selectAllRows();
+ }
+ };
+ final Command unselectAllCommand = new Command() {
+
+ @Override
+ public void execute() {
+ hide();
+ if(GSS.get().isFileListShowing())
+ GSS.get().getFileList().clearSelectedRows();
+ else if(GSS.get().isSearchResultsShowing())
+ GSS.get().getSearchResults().clearSelectedRows();
+ }
+ };
+
+ boolean cutcopyVisible = GSS.get().getCurrentSelection() != null && (GSS.get().getCurrentSelection() instanceof RestResourceWrapper
+ || GSS.get().getCurrentSelection() instanceof FileResource || GSS .get().getCurrentSelection() instanceof GroupUserResource || GSS .get().getCurrentSelection() instanceof List);
+ String cutLabel = "Cut";
+ String copyLabel ="Copy";
+ String pasteLabel = "Paste";
+ if(GSS.get().getCurrentSelection() != null)
+ if(GSS.get().getCurrentSelection() instanceof RestResourceWrapper){
+ cutLabel = "Cut Folder";
+ copyLabel = "Copy Folder";
+ }
+ else if(GSS.get().getCurrentSelection() instanceof FileResource){
+ cutLabel = "Cut File";
+ copyLabel = "Copy File";
+ }
+ else if(GSS.get().getCurrentSelection() instanceof List){
+ cutLabel = "Cut Files";
+ copyLabel = "Copy Files";
+ }
+ if(GSS.get().getClipboard().getItem() != null)
+ if(GSS.get().getClipboard().getItem().getFile() != null)
+ pasteLabel = "Paste File";
+ else if(GSS.get().getClipboard().getItem().getFiles() != null)
+ pasteLabel = "Paste Files";
+ else if(GSS.get().getClipboard().getItem().getRestResourceWrapper() != null)
+ pasteLabel = "Paste Folder";
+ MenuItem cutItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.cut()).getHTML() + " "+cutLabel+"</span>", true, new CutCommand(this));
+ cutItem.getElement().setId("topMenu.edit.cut");
+ contextMenu.addItem(cutItem).setVisible(cutcopyVisible);
+
+ MenuItem copyItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.copy()).getHTML() + " "+copyLabel+"</span>", true, new CopyCommand(this));
+ copyItem.getElement().setId("topMenu.edit.copy");
+ contextMenu.addItem(copyItem).setVisible(cutcopyVisible);
+
+ MenuItem pasteItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.paste()).getHTML() + " "+pasteLabel+"</span>", true, new PasteCommand(this));
+ pasteItem.getElement().setId("topMenu.edit.paste");
+ if (GSS.get().getClipboard().getItem() != null)
+ if(GSS.get().isUserListVisible() && GSS.get().getClipboard().getItem().getUser() == null){
+ contextMenu.addItem(pasteItem);
+ }
+ else if(!GSS.get().isUserListVisible() && GSS.get().getClipboard().getItem().getUser() != null){
+ //do not show paste
+ }
+ else if (GSS.get().getTreeView().getSelection() instanceof RestResourceWrapper){
+ contextMenu.addItem(pasteItem);
+ }
+ MenuItem moveToTrashItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.emptyTrash()).getHTML() + " Move to Trash</span>", true, new ToTrashCommand(this));
+ moveToTrashItem.getElement().setId("topMenu.edit.moveToTrash");
+ contextMenu .addItem(moveToTrashItem)
+ .setVisible(cutcopyVisible);
+
+ MenuItem deleteItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, images));
+ deleteItem.getElement().setId("topMenu.edit.delete");
+ contextMenu .addItem(deleteItem)
+ .setVisible(cutcopyVisible);
+
+ MenuItem selectAllItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.selectAll()).getHTML() + " Select All</span>", true, selectAllCommand);
+ selectAllItem.getElement().setId("topMenu.edit.selectAll");
+ contextMenu.addItem(selectAllItem);
+
+ MenuItem unSelectAllItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.unselectAll()).getHTML() + " Unselect All</span>", true, unselectAllCommand);
+ unSelectAllItem.getElement().setId("topMenu.edit.unSelectAll");
+ contextMenu.addItem(unSelectAllItem);
+ return contextMenu;
+ }
+
+
+
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.commands.CopyCommand;
+import org.gss_project.gss.web.client.commands.CutCommand;
+import org.gss_project.gss.web.client.commands.DeleteCommand;
+import org.gss_project.gss.web.client.commands.PasteCommand;
+import org.gss_project.gss.web.client.commands.PropertiesCommand;
+import org.gss_project.gss.web.client.commands.RefreshCommand;
+import org.gss_project.gss.web.client.commands.RestoreTrashCommand;
+import org.gss_project.gss.web.client.commands.ToTrashCommand;
+import org.gss_project.gss.web.client.commands.UploadFileCommand;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+import org.gss_project.gss.web.client.rest.resource.TrashFolderResource;
+
+import java.util.List;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.ContextMenuEvent;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * The 'File Context' menu implementation.
+ */
+public class FileContextMenu extends PopupPanel implements ClickHandler {
+
+ /**
+ * The widget's images.
+ */
+ private final Images images;
+
+ private MenuItem cutItem;
+
+ private MenuItem copyItem;
+
+ private MenuItem pasteItem;
+
+ private MenuItem updateItem;
+
+ private MenuItem sharingItem;
+
+ private MenuItem propItem;
+
+ private MenuItem trashItem;
+
+ private MenuItem deleteItem;
+
+ private MenuItem downloadItem;
+
+ private MenuItem saveAsItem;
+
+ /**
+ * The image bundle for this widget's images that reuses images defined in
+ * other menus.
+ */
+ public interface Images extends ClientBundle,FileMenu.Images, EditMenu.Images {
+
+ @Source("org/gss_project/gss/resources/mimetypes/document.png")
+ ImageResource fileContextMenu();
+
+ @Source("org/gss_project/gss/resources/doc_versions.png")
+ ImageResource versions();
+
+ @Override
+ @Source("org/gss_project/gss/resources/group.png")
+ ImageResource sharing();
+
+ @Override
+ @Source("org/gss_project/gss/resources/border_remove.png")
+ ImageResource unselectAll();
+
+ @Source("org/gss_project/gss/resources/demo.png")
+ ImageResource viewImage();
+}
+
+ public static native String getDate()/*-{
+ return (new Date()).toUTCString();
+ }-*/;
+
+ /**
+ * The widget's constructor.
+ *
+ * @param newImages the image bundle passed on by the parent object
+ */
+ public FileContextMenu(Images newImages, boolean isTrash, boolean isEmpty) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(true);
+ GSS gss = GSS.get();
+ setAnimationEnabled(true);
+ images = newImages;
+
+ // The command that does some validation before downloading a file.
+ Command downloadCmd = new Command() {
+
+ @Override
+ public void execute() {
+ hide();
+ GSS.get().getTopPanel().getFileMenu().preDownloadCheck();
+ }
+ };
+
+ pasteItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.paste()).getHTML() + " Paste</span>", true, new PasteCommand(this));
+ pasteItem.getElement().setId("FileContextMenu.paste");
+ RestResource sel = GSS.get().getTreeView().getSelection();
+ MenuBar contextMenu = new MenuBar(true);
+ if (isEmpty) {
+ contextMenu.addItem(pasteItem);
+ if (sel != null)
+ /*TODO:CELLTREE
+ if (GSS.get().getTreeView().isFileItem(GSS.get().getTreeView().getCurrent()))
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ else if (GSS.get().getTreeView().isMySharedItem(GSS.get().getTreeView().getCurrent()) || GSS .get()
+ .getTreeView()
+ .isOthersSharedItem(GSS .get()
+ .getTreeView()
+ .getCurrent()))
+ if(sel instanceof FolderResource)
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ */
+ if(sel instanceof RestResourceWrapper && !(sel instanceof TrashFolderResource)){
+ MenuItem upload = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ upload.getElement().setId("fileContextMenu.upload");
+ contextMenu.addItem(upload);
+ }
+ MenuItem refresh = new MenuItem("<span>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ refresh.getElement().setId("fileContextMenu.refresh");
+ contextMenu.addItem(refresh);
+
+ } else if (isTrash) {
+ MenuItem restore = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.versions()).getHTML() + " Restore</span>", true, new RestoreTrashCommand(this));
+ restore.getElement().setId("fileContextMenu.restore");
+ contextMenu.addItem(restore);
+
+ MenuItem delete = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, images));
+ delete.getElement().setId("fileContextMenu.delete");
+ contextMenu.addItem(delete);
+ } else {
+ final Command unselectAllCommand = new Command() {
+
+ @Override
+ public void execute() {
+ hide();
+ if(GSS.get().isFileListShowing())
+ GSS.get().getFileList().clearSelectedRows();
+ else if(GSS.get().isSearchResultsShowing())
+ GSS.get().getSearchResults().clearSelectedRows();
+ }
+ };
+ cutItem = new MenuItem("<span id='fileContextMenu.cut'>" + AbstractImagePrototype.create(newImages.cut()).getHTML() + " Cut</span>", true, new CutCommand(this));
+ cutItem.getElement().setId("fileContextMenu.cut");
+
+ copyItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy</span>", true, new CopyCommand(this));
+ copyItem.getElement().setId("fileContextMenu.copy");
+
+ updateItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ updateItem.getElement().setId("fileContextMenu.upload");
+
+ trashItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.emptyTrash()).getHTML() + " Move to Trash</span>", true, new ToTrashCommand(this));
+ trashItem.getElement().setId("fileContextMenu.moveToTrash");
+
+ deleteItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, images));
+ deleteItem.getElement().setId("fileContextMenu.delete");
+
+ sharingItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Sharing</span>", true, new PropertiesCommand(this, images, 1));
+ sharingItem.getElement().setId("fileContextMenu.sharing");
+
+ propItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties</span>", true, new PropertiesCommand(this, images, 0));
+ propItem.getElement().setId("fileContextMenu.properties");
+
+
+ if(sel!=null && sel instanceof FolderResource)
+ contextMenu.addItem(updateItem);
+ String[] link = {"", ""};
+ gss.getTopPanel().getFileMenu().createDownloadLink(link, false);
+ downloadItem = new MenuItem("<span>" + link[0] + AbstractImagePrototype.create(newImages.download()).getHTML() + " Download" + link[1] + "</span>", true, downloadCmd);
+ downloadItem.getElement().setId("fileContextMenu.download");
+ contextMenu.addItem(downloadItem);
+
+ gss.getTopPanel().getFileMenu().createDownloadLink(link, true);
+ saveAsItem = new MenuItem("<span>" + link[0] + AbstractImagePrototype.create(newImages.download()).getHTML() + " Save As" + link[1] + "</span>", true, downloadCmd);
+ saveAsItem.getElement().setId("fileContextMenu.saveAs");
+ contextMenu.addItem(saveAsItem);
+ contextMenu.addItem(cutItem);
+ contextMenu.addItem(copyItem);
+ if(sel!=null && sel instanceof FolderResource)
+ contextMenu.addItem(pasteItem);
+ MenuItem unSelect = new MenuItem("<span>" + AbstractImagePrototype.create(images.unselectAll()).getHTML() + " Unselect</span>", true, unselectAllCommand);
+ unSelect.getElement().setId("fileContextMenu.unSelect");
+ contextMenu.addItem(unSelect);
+
+ contextMenu.addItem(trashItem);
+ contextMenu.addItem(deleteItem);
+
+ MenuItem refresh = new MenuItem("<span id='fileContextMenu.refresh'>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ refresh.getElement().setId("fileContextMenu.refresh");
+ contextMenu.addItem(refresh);
+
+ contextMenu.addItem(sharingItem);
+ contextMenu.addItem(propItem);
+ }
+ add(contextMenu);
+ if (gss.getClipboard().hasFileItem())
+ pasteItem.setVisible(true);
+ else
+ pasteItem.setVisible(false);
+ }
+
+ void onMultipleSelection() {
+ updateItem.setVisible(false);
+ downloadItem.setVisible(false);
+ saveAsItem.setVisible(false);
+ sharingItem.setVisible(false);
+ }
+ @Override
+ public void onClick(ClickEvent event) {
+ if (GSS.get().getCurrentSelection() != null)
+ if (GSS.get().getCurrentSelection() instanceof FileResource) {
+ FileResource res = (FileResource) GSS.get().getCurrentSelection();
+ FileContextMenu menu;
+ if (res.isDeleted())
+ menu = new FileContextMenu(images, true, false);
+ else
+ menu = new FileContextMenu(images, false, false);
+ int left = event.getRelativeElement().getAbsoluteLeft();
+ int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight();
+ menu.setPopupPosition(left, top);
+ menu.show();
+ } else if (GSS.get().getCurrentSelection() instanceof List) {
+ FileContextMenu menu;
+ /*TODO: CELLTREE
+ if (GSS.get().getTreeView().isTrashItem(GSS.get().getTreeView().getCurrent()))
+ menu = new FileContextMenu(images, true, false);
+ else {
+ menu = new FileContextMenu(images, false, false);
+ menu.onMultipleSelection();
+ }
+ */
+ menu = new FileContextMenu(images, false, false);
+ menu.onMultipleSelection();
+ int left = event.getRelativeElement().getAbsoluteLeft();
+ int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight();
+ menu.setPopupPosition(left, top);
+ menu.show();
+ }
+ }
+
+
+ public void onContextEvent(ContextMenuEvent event) {
+ if (GSS.get().getCurrentSelection() != null)
+ if (GSS.get().getCurrentSelection() instanceof FileResource) {
+ FileResource res = (FileResource) GSS.get().getCurrentSelection();
+ FileContextMenu menu;
+ if (res.isDeleted())
+ menu = new FileContextMenu(images, true, false);
+ else
+ menu = new FileContextMenu(images, false, false);
+ int left = event.getNativeEvent().getClientX();
+ int top = event.getNativeEvent().getClientY();
+ menu.setPopupPosition(left, top);
+ menu.show();
+
+ } else if (GSS.get().getCurrentSelection() instanceof List) {
+ FileContextMenu menu;
+ /*TODO: CELLTREE
+ if (GSS.get().getTreeView().isTrashItem(GSS.get().getTreeView().getCurrent()))
+ menu = new FileContextMenu(images, true, false);
+ else {
+ menu = new FileContextMenu(images, false, false);
+ menu.onMultipleSelection();
+ }
+ */
+ int left = event.getNativeEvent().getClientX();
+ int top = event.getNativeEvent().getClientY();
+ //menu.setPopupPosition(left, top);
+ //menu.show();
+ }
+ }
+
+ public FileContextMenu onEvent(Event event) {
+ FileContextMenu menu=null;
+ if (GSS.get().getCurrentSelection() != null)
+ if (GSS.get().getCurrentSelection() instanceof FileResource) {
+ FileResource res = (FileResource) GSS.get().getCurrentSelection();
+
+ if (res.isDeleted())
+ menu = new FileContextMenu(images, true, false);
+ else
+ menu = new FileContextMenu(images, false, false);
+ int left = event.getClientX();
+ int top = event.getClientY();
+ menu.setPopupPosition(left, top);
+ menu.show();
+ } else if (GSS.get().getCurrentSelection() instanceof List) {
+ /*TODO: CELLTREE
+ if (GSS.get().getTreeView().isTrashItem(GSS.get().getTreeView().getSelection()))
+ menu = new FileContextMenu(images, true, false);
+ else {
+ menu = new FileContextMenu(images, false, false);
+ menu.onMultipleSelection();
+ }*/
+ menu = new FileContextMenu(images, false, false);
+ menu.onMultipleSelection();
+ int left = event.getClientX();
+ int top = event.getClientY();
+ menu.setPopupPosition(left, top);
+ menu.show();
+ }
+ return menu;
+ }
+
+ public FileContextMenu onEmptyEvent(Event event) {
+ FileContextMenu menu=null;
+ /*TODO: CELLTREE
+ if (GSS.get().getTreeView().isTrashItem(GSS.get().getTreeView().getCurrent()))
+ menu = new FileContextMenu(images, true, true);
+ else if(((DnDTreeItem)GSS.get().getTreeView().getCurrent()).getFolderResource() != null)
+ menu = new FileContextMenu(images, false, true);
+ else return menu;
+ */
+ menu = new FileContextMenu(images, false, true);
+ int left = event.getClientX();
+ int top = event.getClientY();
+ menu.setPopupPosition(left, top);
+ menu.show();
+ return menu;
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+
+import org.gss_project.gss.web.client.commands.UploadFileCommand;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.RestCommand;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.OtherUserResource;
+import org.gss_project.gss.web.client.rest.resource.OthersFolderResource;
+import org.gss_project.gss.web.client.rest.resource.OthersResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashFolderResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import org.gss_project.gss.web.client.rest.resource.UserSearchResource;
+import gwtquery.plugins.draggable.client.DraggableOptions;
+import gwtquery.plugins.draggable.client.StopDragException;
+import gwtquery.plugins.draggable.client.DraggableOptions.DragFunction;
+import gwtquery.plugins.draggable.client.DraggableOptions.RevertOption;
+import gwtquery.plugins.draggable.client.events.DragContext;
+import gwtquery.plugins.draggable.client.events.DragStartEvent;
+import gwtquery.plugins.draggable.client.events.DragStopEvent;
+import gwtquery.plugins.draggable.client.events.DragStartEvent.DragStartEventHandler;
+import gwtquery.plugins.draggable.client.events.DragStopEvent.DragStopEventHandler;
+import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTable;
+import gwtquery.plugins.droppable.client.gwt.DragAndDropColumn;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import com.google.gwt.cell.client.AbstractCell;
+import com.google.gwt.cell.client.ImageResourceCell;
+import com.google.gwt.cell.client.SafeHtmlCell;
+import com.google.gwt.cell.client.TextCell;
+import com.google.gwt.cell.client.ValueUpdater;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.RepeatingCommand;
+import com.google.gwt.dom.client.Style.Cursor;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.safehtml.client.SafeHtmlTemplates;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.user.cellview.client.CellTable;
+import com.google.gwt.user.cellview.client.GssSimplePager;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.view.client.ListDataProvider;
+import com.google.gwt.view.client.MultiSelectionModel;
+import com.google.gwt.view.client.ProvidesKey;
+import com.google.gwt.view.client.SelectionChangeEvent;
+import com.google.gwt.view.client.SelectionChangeEvent.Handler;
+
+/**
+ * A composite that displays the list of files in a particular folder.
+ */
+public class FileList extends Composite {
+ ListDataProvider<FileResource> provider = new ListDataProvider<FileResource>();
+ interface TableResources extends DragAndDropCellTable.Resources {
+ @Source({CellTable.Style.DEFAULT_CSS, "GssCellTable.css"})
+ TableStyle cellTableStyle();
+ }
+
+ static interface Templates extends SafeHtmlTemplates {
+ Templates INSTANCE = GWT.create(Templates.class);
+
+ @Template("<div id='dragHelper' style='border:1px solid black; background-color:#ffffff; color:black; width:150px;z-index:100'></div>")
+ SafeHtml outerHelper();
+
+ @Template("<span id='{0}'>{0}</span>")
+ public SafeHtml filenameSpan(String filename);
+
+ @Template("<a href='{0}' title='{1}' rel='lytebox[mnf]' onclick='myLytebox.start(this, false, false); return false;'>(view)</a>")
+ public SafeHtml viewLink(String link, String title);
+
+ @Template("<table><tr><td rowspan='3'>{0}</td><td style='font-size:95%;' id='{1}'>{1}</td></tr><tr><td>{2}</td></tr></table>")
+ public SafeHtml rendelContactCell(String imageHtml, String name, String fileSize);
+
+ @Template("<span id='{0}' class='{1}'>{2}</span>")
+ public SafeHtml spanWithIdAndClass(String id, String cssClass, String content);
+ }
+
+
+ /**
+ * The styles applied to the table.
+ */
+ interface TableStyle extends CellTable.Style {
+ }
+
+ private String showingStats = "";
+
+ private int startIndex = 0;
+
+ /**
+ * A constant that denotes the completion of an IncrementalCommand.
+ */
+ public static final boolean DONE = false;
+
+
+
+ private final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
+
+ /**
+ * Specifies that the images available for this composite will be the ones
+ * available in FileContextMenu.
+ */
+ public interface Images extends ClientBundle,FileContextMenu.Images, CellTreeView.Images {
+
+ @Source("org/gss_project/gss/resources/blank.gif")
+ ImageResource blank();
+
+ @Source("org/gss_project/gss/resources/asc.png")
+ ImageResource asc();
+
+ @Source("org/gss_project/gss/resources/desc.png")
+ ImageResource desc();
+
+ @Source("org/gss_project/gss/resources/mimetypes/document_shared.png")
+ ImageResource documentShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/kcmfontinst.png")
+ ImageResource wordprocessor();
+
+ @Source("org/gss_project/gss/resources/mimetypes/log.png")
+ ImageResource spreadsheet();
+
+ @Source("org/gss_project/gss/resources/mimetypes/kpresenter_kpr.png")
+ ImageResource presentation();
+
+ @Source("org/gss_project/gss/resources/mimetypes/acroread.png")
+ ImageResource pdf();
+
+ @Source("org/gss_project/gss/resources/mimetypes/image.png")
+ ImageResource image();
+
+ @Source("org/gss_project/gss/resources/mimetypes/video2.png")
+ ImageResource video();
+
+ @Source("org/gss_project/gss/resources/mimetypes/knotify.png")
+ ImageResource audio();
+
+ @Source("org/gss_project/gss/resources/mimetypes/html.png")
+ ImageResource html();
+
+ @Source("org/gss_project/gss/resources/mimetypes/txt.png")
+ ImageResource txt();
+
+ @Source("org/gss_project/gss/resources/mimetypes/ark2.png")
+ ImageResource zip();
+
+ @Source("org/gss_project/gss/resources/mimetypes/kcmfontinst_shared.png")
+ ImageResource wordprocessorShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/log_shared.png")
+ ImageResource spreadsheetShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/kpresenter_kpr_shared.png")
+ ImageResource presentationShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/acroread_shared.png")
+ ImageResource pdfShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/image_shared.png")
+ ImageResource imageShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/video2_shared.png")
+ ImageResource videoShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/knotify_shared.png")
+ ImageResource audioShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/html_shared.png")
+ ImageResource htmlShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/txt_shared.png")
+ ImageResource txtShared();
+
+ @Source("org/gss_project/gss/resources/mimetypes/ark2_shared.png")
+ ImageResource zipShared();
+
+ }
+
+ DragStopEventHandler dragStop = new DragStopEventHandler() {
+
+ @Override
+ public void onDragStop(DragStopEvent event) {
+ GWT.log("DRAG STOPPED");
+
+ }
+ };
+
+ private static class ContactCell extends AbstractCell<org.gss_project.gss.web.client.rest.resource.FileResource> {
+
+ /**
+ * The html of the image used for contacts.
+ *
+ */
+ private final String imageHtml;
+
+ public ContactCell(ImageResource image) {
+ this.imageHtml = AbstractImagePrototype.create(image).getHTML();
+ }
+
+
+
+
+
+ @Override
+ public void render(Context context, FileResource value, SafeHtmlBuilder sb) {
+ // Value can be null, so do a null check..
+ if (value == null) {
+ return;
+ }
+
+ sb.append(Templates.INSTANCE.rendelContactCell(imageHtml, value.getName(), value.getFileSizeAsString()));
+ }
+
+
+ }
+ /**
+ * Retrieve the celltable.
+ *
+ * @return the celltable
+ */
+ public DragAndDropCellTable<FileResource> getCelltable() {
+ return celltable;
+ }
+
+
+ /**
+ * The number of files in this folder.
+ */
+ int folderFileCount;
+
+ /**
+ * Total folder size
+ */
+ long folderTotalSize;
+
+ /**
+ * A cache of the files in the list.
+ */
+ private List<FileResource> files;
+
+ /**
+ * The widget's image bundle.
+ */
+ private final Images images;
+
+ private FileContextMenu menuShowing;
+ private DragAndDropCellTable<FileResource> celltable;
+ private final MultiSelectionModel<FileResource> selectionModel;
+ private final List<SortableHeader> allHeaders = new ArrayList<SortableHeader>();
+ SortableHeader nameHeader;
+ GssSimplePager pagerBottom;
+ GssSimplePager pagerTop;
+ Button uploadButtonBottom;
+ Button uploadButtonTop;
+ /**
+ * Construct the file list widget. This entails setting up the widget
+ * layout, fetching the number of files in the current folder from the
+ * server and filling the local file cache of displayed files with data from
+ * the server, as well.
+ *
+ * @param _images
+ */
+ public FileList(Images _images) {
+ images = _images;
+ DragAndDropCellTable.Resources resources = GWT.create(TableResources.class);
+ ProvidesKey<FileResource> keyProvider = new ProvidesKey<FileResource>(){
+
+ @Override
+ public Object getKey(FileResource item) {
+ return item.getUri();
+ }
+
+ };
+ celltable = new DragAndDropCellTable<FileResource>(GSS.VISIBLE_FILE_COUNT,resources,keyProvider);
+
+ DragAndDropColumn<FileResource, ImageResource> status = new DragAndDropColumn<FileResource, ImageResource>(new ImageResourceCell(){
+ @Override
+ public boolean handlesSelection() {
+ return false;
+ }
+ }) {
+ @Override
+ public ImageResource getValue(FileResource entity) {
+ return getFileIcon(entity);
+ }
+
+ };
+ celltable.addColumn(status,"");
+
+ initDragOperation(status);
+ final DragAndDropColumn<FileResource,SafeHtml> nameColumn = new DragAndDropColumn<FileResource,SafeHtml>(new SafeHtmlCell()) {
+
+ @Override
+ public SafeHtml getValue(FileResource object) {
+ SafeHtmlBuilder sb = new SafeHtmlBuilder();
+ sb.append(Templates.INSTANCE.filenameSpan(object.getName()));
+ if (object.getContentType().endsWith("png") || object.getContentType().endsWith("gif") || object.getContentType().endsWith("jpeg") ){
+ sb.appendHtmlConstant(" ").append(Templates.INSTANCE.viewLink(GSS.get().getTopPanel().getFileMenu().getDownloadURL(object), object.getOwner() + " : " + object.getPath() + object.getName()));
+ }
+
+ return sb.toSafeHtml();
+ }
+
+ };
+ initDragOperation(nameColumn);
+ celltable.addColumn(nameColumn,nameHeader = new SortableHeader("Name"));
+ allHeaders.add(nameHeader);
+ //nameHeader.setSorted(true);
+ //nameHeader.toggleReverseSort();
+ nameHeader.setUpdater(new FileValueUpdater(nameHeader, "name"));
+ celltable.redrawHeaders();
+
+
+
+
+ SortableHeader aheader;
+ DragAndDropColumn<FileResource,String> aColumn;
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ return GSS.get().findUserFullName(object.getOwner());
+ }
+ },aheader = new SortableHeader("Owner"));
+ initDragOperation(aColumn);
+ allHeaders.add(aheader);
+ aheader.setUpdater(new FileValueUpdater(aheader, "owner"));
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ // TODO Auto-generated method stub
+ return object.getPath();
+ }
+ },aheader = new SortableHeader("Path"));
+ initDragOperation(aColumn);
+ allHeaders.add(aheader);
+
+ aheader.setUpdater(new FileValueUpdater(aheader, "path"));
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ if(object.isVersioned())
+ return object.getVersion().toString();
+ return "-";
+ }
+ },aheader = new SortableHeader("Version"));
+ initDragOperation(aColumn);
+ allHeaders.add(aheader);
+ aheader.setUpdater(new FileValueUpdater(aheader, "version"));
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ // TODO Auto-generated method stub
+ return object.getFileSizeAsString();
+ }
+ },aheader = new SortableHeader("Size"));
+ initDragOperation(aColumn);
+ allHeaders.add(aheader);
+ aheader.setUpdater(new FileValueUpdater(aheader, "size"));
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ return formatter.format(object.getModificationDate());
+ }
+ },aheader = new SortableHeader("Last Modified"));
+ allHeaders.add(aheader);
+ aheader.setUpdater(new FileValueUpdater(aheader, "date"));
+
+
+ provider.addDataDisplay(celltable);
+ celltable.addDragStopHandler(dragStop);
+ celltable.addDragStartHandler(new DragStartEventHandler() {
+
+ public void onDragStart(DragStartEvent event) {
+ FileResource value = event.getDraggableData();
+
+ com.google.gwt.dom.client.Element helper = event.getHelper();
+ SafeHtmlBuilder sb = new SafeHtmlBuilder();
+ sb.appendHtmlConstant("<b>");
+ DisplayHelper.log(value.getName());
+ if(getSelectedFiles().size()==1)
+ sb.appendEscaped(value.getName());
+ else
+ sb.appendEscaped(getSelectedFiles().size()+" files");
+ sb.appendHtmlConstant("</b>");
+ helper.setInnerHTML(sb.toSafeHtml().asString());
+
+ }
+ });
+
+
+
+
+
+
+ VerticalPanel vp = new VerticalPanel();
+ vp.setWidth("100%");
+ pagerTop = new GssSimplePager(GssSimplePager.TextLocation.CENTER);
+ pagerTop.setDisplay(celltable);
+ uploadButtonTop=new Button("<span id='topMenu.file.upload'>" + AbstractImagePrototype.create(images.fileUpdate()).getHTML() + " Upload</span>");
+ uploadButtonTop.addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ new UploadFileCommand(null).execute();
+ }
+ });
+ HorizontalPanel topPanel = new HorizontalPanel();
+ topPanel.add(pagerTop);
+ topPanel.add(uploadButtonTop);
+ vp.add(topPanel);
+ celltable.setWidth("100%");
+ vp.add(celltable);
+ pagerBottom = new GssSimplePager(GssSimplePager.TextLocation.CENTER);
+ pagerBottom.setDisplay(celltable);
+ HorizontalPanel bottomPanel = new HorizontalPanel();
+ bottomPanel.add(pagerBottom);
+ uploadButtonBottom=new Button("<span id='topMenu.file.upload'>" + AbstractImagePrototype.create(images.fileUpdate()).getHTML() + " Upload</span>");
+ uploadButtonBottom.addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ new UploadFileCommand(null).execute();
+ }
+ });
+ bottomPanel.add(uploadButtonBottom);
+ vp.add(bottomPanel);
+ vp.setCellWidth(celltable, "100%");
+
+ initWidget(vp);
+ pagerBottom.setVisible(false);
+ pagerTop.setVisible(false);
+
+ celltable.setStyleName("gss-List");
+ selectionModel = new MultiSelectionModel<FileResource>(keyProvider);
+
+
+ Handler selectionHandler = new SelectionChangeEvent.Handler() {
+ @Override
+ public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
+ if(getSelectedFiles().size()==1)
+ GSS.get().setCurrentSelection(getSelectedFiles().get(0));
+ else
+ GSS.get().setCurrentSelection(getSelectedFiles());
+ }
+ };
+ selectionModel.addSelectionChangeHandler(selectionHandler);
+
+ celltable.setSelectionModel(selectionModel,GSSSelectionEventManager.<FileResource>createDefaultManager());
+ celltable.setPageSize(GSS.VISIBLE_FILE_COUNT);
+
+ //celltable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
+ Scheduler.get().scheduleIncremental(new RepeatingCommand() {
+
+ @Override
+ public boolean execute() {
+ return fetchRootFolder();
+ }
+ });
+ sinkEvents(Event.ONCONTEXTMENU);
+ sinkEvents(Event.ONMOUSEUP);
+ sinkEvents(Event.ONMOUSEDOWN);
+ sinkEvents(Event.ONCLICK);
+ sinkEvents(Event.ONKEYDOWN);
+ sinkEvents(Event.ONDBLCLICK);
+ GSS.preventIESelection();
+ }
+
+ //public native void fireClickEvent(Element element) /*-{
+ // var evObj = $doc.createEvent('MouseEvents');
+ //evObj.initEvent('click', true, true);
+ //element.dispatchEvent(evObj);
+ //}-*/;
+
+
+
+ public List<FileResource> getSelectedFiles() {
+ return new ArrayList<FileResource>(selectionModel.getSelectedSet());
+ }
+
+ private void initDragOperation(DragAndDropColumn<?, ?> column) {
+
+ // retrieve draggableOptions on the column
+ DraggableOptions draggableOptions = column.getDraggableOptions();
+ // use template to construct the helper. The content of the div will be set
+ // after
+ draggableOptions.setHelper($(Templates.INSTANCE.outerHelper().asString()));
+ //draggableOptions.setZIndex(100);
+ // opacity of the helper
+ draggableOptions.setAppendTo("body");
+ //draggableOptions.setOpacity((float) 0.8);
+ draggableOptions.setContainment("document");
+ // cursor to use during the drag operation
+ draggableOptions.setCursor(Cursor.MOVE);
+ // set the revert option
+ draggableOptions.setRevert(RevertOption.ON_INVALID_DROP);
+ // prevents dragging when user click on the category drop-down list
+ draggableOptions.setCancel("select");
+
+
+ draggableOptions.setOnBeforeDragStart(new DragFunction() {
+
+ @Override
+ public void f(DragContext context) {
+ FileResource value = context.getDraggableData();
+ if(!selectionModel.isSelected(value)){
+ throw new StopDragException();
+ }
+
+ }
+ });
+ }
+
+ public void showContextMenu(Event event){
+ menuShowing = new FileContextMenu(images, false, true);
+ menuShowing=menuShowing.onEmptyEvent(event);
+ }
+ @Override
+ public void onBrowserEvent(Event event) {
+
+ if (files == null || files.size() == 0) {
+ if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
+ menuShowing = new FileContextMenu(images, false, true);
+ menuShowing=menuShowing.onEmptyEvent(event);
+ event.preventDefault();
+ event.cancelBubble(true);
+ }
+ return;
+ }
+ if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() != 0) {
+ GWT.log("*****GOING TO SHOW CONTEXT MENU ****", null);
+ menuShowing = new FileContextMenu(images, false, false);
+ menuShowing=menuShowing.onEvent(event);
+ event.cancelBubble(true);
+ event.preventDefault();
+ } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
+ menuShowing = new FileContextMenu(images, false, true);
+ menuShowing=menuShowing.onEmptyEvent(event);
+ event.cancelBubble(true);
+ event.preventDefault();
+ } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
+ if (getSelectedFiles().size() == 1) {
+ GSS app = GSS.get();
+ FileResource file = getSelectedFiles().get(0);
+ String dateString = RestCommand.getDate();
+ String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
+ String sig = app.getCurrentUserResource().getUsername() + " " +
+ RestCommand.calculateSig("GET", dateString, resource,
+ RestCommand.base64decode(app.getToken()));
+ Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
+ event.preventDefault();
+ return;
+ }
+ super.onBrowserEvent(event);
+ }
+
+ /**
+ * Retrieve the root folder for the current user.
+ *
+ * @return true if the retrieval was successful
+ */
+ protected boolean fetchRootFolder() {
+ UserResource user = GSS.get().getCurrentUserResource();
+ if (user == null)
+ return !DONE;
+ // Update cache and clear selection.
+ updateFileCache(true);
+ return DONE;
+ }
+
+
+ /**
+ * Update the display of the file list.
+ */
+ void update(boolean sort) {
+ int count = folderFileCount;
+ int max = startIndex + GSS.VISIBLE_FILE_COUNT;
+ if (max > count)
+ max = count;
+ folderTotalSize = 0;
+
+ copyListAndContinue(files);
+ for(FileResource f : files){
+ folderTotalSize += f.getContentLength();
+ }
+ if (folderFileCount == 0) {
+ showingStats = "no files";
+ } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
+ if (folderFileCount == 1)
+ showingStats = "1 file";
+ else
+ showingStats = folderFileCount + " files";
+ showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
+ } else {
+ showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
+ }
+ showCellTable();
+ updateCurrentlyShowingStats();
+
+ }
+
+ /**
+ * Return the proper icon based on the MIME type of the file.
+ *
+ * @param file
+ * @return the icon
+ */
+ private ImageResource getFileIcon(FileResource file) {
+ String mimetype = file.getContentType();
+ boolean shared = false;
+ if(GSS.get().getTreeView().getSelection()!=null && (GSS.get().getTreeView().getSelection() instanceof OtherUserResource || GSS.get().getTreeView().getSelection() instanceof OthersFolderResource)){
+ OtherUserResource otherUser = null;
+ if(GSS.get().getTreeView().getSelection() instanceof OtherUserResource)
+ otherUser = (OtherUserResource) GSS.get().getTreeView().getSelection();
+ else if (GSS.get().getTreeView().getSelection() instanceof OthersFolderResource){
+ otherUser = GSS.get().getTreeView().getOtherUserResourceOfOtherFolder((OthersFolderResource) GSS.get().getTreeView().getSelection());
+ }
+ if(otherUser ==null)
+ shared=false;
+ else{
+ String uname = otherUser.getUsername();
+ if(uname==null)
+ uname = GSS.get().getTreeView().getOthers().getUsernameOfUri(otherUser.getUri());
+ if(uname != null)
+ shared = file.isShared();
+ }
+ }
+ else
+ shared = file.isShared();
+ if (mimetype == null)
+ return shared ? images.documentShared() : images.document();
+ mimetype = mimetype.toLowerCase();
+ if (mimetype.startsWith("application/pdf"))
+ return shared ? images.pdfShared() : images.pdf();
+ else if (mimetype.endsWith("excel"))
+ return shared ? images.spreadsheetShared() : images.spreadsheet();
+ else if (mimetype.endsWith("msword"))
+ return shared ? images.wordprocessorShared() : images.wordprocessor();
+ else if (mimetype.endsWith("powerpoint"))
+ return shared ? images.presentationShared() : images.presentation();
+ else if (mimetype.startsWith("application/zip") ||
+ mimetype.startsWith("application/gzip") ||
+ mimetype.startsWith("application/x-gzip") ||
+ mimetype.startsWith("application/x-tar") ||
+ mimetype.startsWith("application/x-gtar"))
+ return shared ? images.zipShared() : images.zip();
+ else if (mimetype.startsWith("text/html"))
+ return shared ? images.htmlShared() : images.html();
+ else if (mimetype.startsWith("text/plain"))
+ return shared ? images.txtShared() : images.txt();
+ else if (mimetype.startsWith("image/"))
+ return shared ? images.imageShared() : images.image();
+ else if (mimetype.startsWith("video/"))
+ return shared ? images.videoShared() : images.video();
+ else if (mimetype.startsWith("audio/"))
+ return shared ? images.audioShared() : images.audio();
+ return shared ? images.documentShared() : images.document();
+ }
+
+ /**
+ * Update status panel with currently showing file stats.
+ */
+ public void updateCurrentlyShowingStats() {
+ GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
+ }
+
+ public void updateFileCache(boolean clearSelection){
+ if(clearSelection){
+ clearSelectedRows();
+ }
+
+ final RestResource folderItem = GSS.get().getTreeView().getSelection();
+ // Validation.
+ if (folderItem == null || folderItem.equals(GSS.get().getTreeView().getOthers())) {
+ setFiles(new ArrayList<FileResource>());
+ update(true);
+ return;
+ }
+ else if (folderItem instanceof RestResourceWrapper) {
+ setFiles(((RestResourceWrapper) folderItem).getResource().getFiles());
+ update(true);
+ }
+ else if (folderItem instanceof SharedResource) {
+ setFiles(((SharedResource) folderItem).getFiles());
+ update(true);
+ }
+ else if (folderItem instanceof OtherUserResource) {
+ setFiles(((OtherUserResource) folderItem).getFiles());
+ update(true);
+ }
+ else if (folderItem instanceof TrashResource) {
+ setFiles(((TrashResource) folderItem).getFiles());
+ update(true);
+ }
+ }
+
+
+ /**
+ * Fill the file cache with data.
+ */
+ public void setFiles(final List<FileResource> _files) {
+ if (_files.size() > 0 && ! (GSS.get().getTreeView().getSelection() instanceof TrashResource)) {
+ files = new ArrayList<FileResource>();
+ for (FileResource fres : _files)
+ if (!fres.isDeleted())
+ files.add(fres);
+ }
+ else
+ files = _files;
+ Collections.sort(files, new Comparator<FileResource>() {
+
+ @Override
+ public int compare(FileResource arg0, FileResource arg1) {
+ return arg0.getName().compareTo(arg1.getName());
+ }
+
+ });
+ folderFileCount = files.size();
+
+ nameHeader.setSorted(true);
+ nameHeader.toggleReverseSort();
+ for (SortableHeader otherHeader : allHeaders) {
+ if (otherHeader != nameHeader) {
+ otherHeader.setSorted(false);
+ otherHeader.setReverseSort(true);
+ }
+ }
+ //
+ }
+
+
+
+
+ /**
+ * Does the list contains the requested filename
+ *
+ * @param fileName
+ * @return true/false
+ */
+ public boolean contains(String fileName) {
+ for (int i = 0; i < files.size(); i++)
+ if (files.get(i).getName().equals(fileName))
+ return true;
+ return false;
+ }
+
+ public void clearSelectedRows() {
+ Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
+ while(it.hasNext()){
+ selectionModel.setSelected(it.next(),false);
+ }
+ }
+
+
+ /**
+ *
+ */
+ public void selectAllRows() {
+ Iterator<FileResource> it = provider.getList().iterator();
+ while(it.hasNext()){
+ selectionModel.setSelected(it.next(),true);
+ }
+
+
+ }
+
+
+ private void sortFiles(final String sortingProperty, final boolean sortingType){
+ Collections.sort(files, new Comparator<FileResource>() {
+
+ @Override
+ public int compare(FileResource arg0, FileResource arg1) {
+ AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
+ AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
+ if (sortingType){
+ if (sortingProperty.equals("version")) {
+ return arg0.getVersion().compareTo(arg1.getVersion());
+ } else if (sortingProperty.equals("owner")) {
+ return arg0.getOwner().compareTo(arg1.getOwner());
+ } else if (sortingProperty.equals("date")) {
+ return arg0.getModificationDate().compareTo(arg1.getModificationDate());
+ } else if (sortingProperty.equals("size")) {
+ return arg0.getContentLength().compareTo(arg1.getContentLength());
+ } else if (sortingProperty.equals("name")) {
+ return arg0.getName().compareTo(arg1.getName());
+ } else if (sortingProperty.equals("path")) {
+ return arg0.getUri().compareTo(arg1.getUri());
+ } else {
+ return arg0.getName().compareTo(arg1.getName());
+ }
+ }
+ else if (sortingProperty.equals("version")) {
+
+ return arg1.getVersion().compareTo(arg0.getVersion());
+ } else if (sortingProperty.equals("owner")) {
+
+ return arg1.getOwner().compareTo(arg0.getOwner());
+ } else if (sortingProperty.equals("date")) {
+
+ return arg1.getModificationDate().compareTo(arg0.getModificationDate());
+ } else if (sortingProperty.equals("size")) {
+
+ return arg1.getContentLength().compareTo(arg0.getContentLength());
+ } else if (sortingProperty.equals("name")) {
+
+ return arg1.getName().compareTo(arg0.getName());
+ } else if (sortingProperty.equals("path")) {
+
+ return arg1.getUri().compareTo(arg0.getUri());
+ } else {
+
+ return arg1.getName().compareTo(arg0.getName());
+ }
+ }
+
+ });
+ }
+
+ final class FileValueUpdater implements ValueUpdater<String>{
+ private String property;
+ private SortableHeader header;
+ /**
+ *
+ */
+ public FileValueUpdater(SortableHeader header,String property) {
+ this.property=property;
+ this.header=header;
+ }
+ @Override
+ public void update(String value) {
+ header.setSorted(true);
+ header.toggleReverseSort();
+
+ for (SortableHeader otherHeader : allHeaders) {
+ if (otherHeader != header) {
+ otherHeader.setSorted(false);
+ otherHeader.setReverseSort(true);
+ }
+ }
+ celltable.redrawHeaders();
+ sortFiles(property, header.getReverseSort());
+ FileList.this.update(true);
+ }
+
+ }
+ /**
+ * Creates a new ArrayList<FileResources> from the given files ArrayList
+ * in order that the input files remain untouched
+ * and continues to find user's full names of each FileResource element
+ * in the new ArrayList
+ *
+ * @param filesInput
+ */
+ private void copyListAndContinue(List<FileResource> filesInput){
+ List<FileResource> copiedFiles = new ArrayList<FileResource>();
+ for(FileResource file : filesInput) {
+ copiedFiles.add(file);
+ }
+ handleFullNames(copiedFiles);
+ }
+
+ /**
+ * Examines whether or not the user's full name exists in the
+ * userFullNameMap in the GSS.java for every element of the input list.
+ * If the user's full name does not exist in the map then a command is being made.
+ *
+ * @param filesInput
+ */
+ private void handleFullNames(List<FileResource> filesInput){
+ if(filesInput.size() == 0){
+ showCellTable();
+ return;
+ }
+
+ if(GSS.get().findUserFullName(filesInput.get(0).getOwner()) == null){
+ findFullNameAndUpdate(filesInput);
+ return;
+ }
+
+ if(filesInput.size() >= 1){
+ filesInput.remove(filesInput.get(0));
+ if(filesInput.isEmpty()){
+ showCellTable();
+ }else{
+ handleFullNames(filesInput);
+ }
+ }
+ }
+
+ /**
+ * Makes a command to search for full name from a given username.
+ * Only after the completion of the command the celltable is shown
+ * or the search for the next full name continues.
+ *
+ * @param filesInput
+ */
+ private void findFullNameAndUpdate(final List<FileResource> filesInput){
+ String aUserName = filesInput.get(0).getOwner();
+ String path = GSS.get().getApiPath() + "users/" + aUserName;
+
+ GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
+ @Override
+ public void onComplete() {
+ final UserSearchResource result = getResult();
+ for (UserResource user : result.getUsers()){
+ String username = user.getUsername();
+ String userFullName = user.getName();
+ GSS.get().putUserToMap(username, userFullName);
+ if(filesInput.size() >= 1){
+ filesInput.remove(filesInput.get(0));
+ if(filesInput.isEmpty()){
+ showCellTable();
+ }else{
+ handleFullNames(filesInput);
+ }
+ }
+ }
+ }
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch user's full name from the given username " + filesInput.get(0).getOwner());
+ if(filesInput.size() >= 1){
+ filesInput.remove(filesInput.get(0));
+ handleFullNames(filesInput);
+ }
+ }
+ };
+ DeferredCommand.addCommand(gg);
+
+ }
+ /**
+ * Shows the files in the cellTable
+ */
+
+ private void showCellTable(){
+ if(files.size()>GSS.VISIBLE_FILE_COUNT){
+ pagerBottom.setVisible(true);
+ pagerTop.setVisible(true);
+ }
+ else{
+ pagerTop.setVisible(false);
+ pagerBottom.setVisible(false);
+ }
+ RestResource selectedItem = GSS.get().getTreeView().getSelection();
+ boolean uploadVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource));
+ uploadButtonBottom.setVisible(uploadVisible&&files.size()>=GSS.VISIBLE_FILE_COUNT);
+ uploadButtonTop.setVisible(uploadVisible&&files.size()>=GSS.VISIBLE_FILE_COUNT);
+ provider.setList(files);
+
+ provider.refresh();
+
+ //celltable.redraw();
+ celltable.redrawHeaders();
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.commands.EmptyTrashCommand;
+import org.gss_project.gss.web.client.commands.NewFolderCommand;
+import org.gss_project.gss.web.client.commands.PropertiesCommand;
+import org.gss_project.gss.web.client.commands.RefreshCommand;
+import org.gss_project.gss.web.client.commands.UploadFileCommand;
+import org.gss_project.gss.web.client.rest.RestCommand;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.OtherUserResource;
+import org.gss_project.gss.web.client.rest.resource.OthersResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashFolderResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+
+import java.util.List;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * The 'File' menu implementation.
+ */
+public class FileMenu extends PopupPanel implements ClickHandler {
+
+ /**
+ * The widget's images.
+ */
+ private final Images images;
+
+ /**
+ * An image bundle for this widgets images.
+ */
+ public interface Images extends ClientBundle,FilePropertiesDialog.Images {
+
+ @Source("org/gss_project/gss/resources/folder_new.png")
+ ImageResource folderNew();
+
+ @Source("org/gss_project/gss/resources/folder_outbox.png")
+ ImageResource fileUpdate();
+
+ @Source("org/gss_project/gss/resources/view_text.png")
+ ImageResource viewText();
+
+ @Override
+ @Source("org/gss_project/gss/resources/folder_inbox.png")
+ ImageResource download();
+
+ @Source("org/gss_project/gss/resources/trashcan_empty.png")
+ ImageResource emptyTrash();
+
+ @Source("org/gss_project/gss/resources/internet.png")
+ ImageResource sharing();
+
+ @Source("org/gss_project/gss/resources/refresh.png")
+ ImageResource refresh();
+}
+
+ final MenuBar contextMenu = new MenuBar(true);
+
+ /**
+ * The widget's constructor.
+ *
+ * @param _images the image bundle passed on by the parent object
+ */
+ public FileMenu(final Images _images) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(true);
+ setAnimationEnabled(true);
+ images = _images;
+ add(contextMenu);
+
+ }
+
+ @Override
+ public void onClick(ClickEvent event) {
+ final FileMenu menu = new FileMenu(images);
+ final int left = event.getRelativeElement().getAbsoluteLeft();
+ final int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight();
+ menu.setPopupPosition(left, top);
+ menu.show();
+
+ }
+
+
+ /**
+ * Do some validation before downloading a file.
+ */
+ void preDownloadCheck() {
+ Object selection = GSS.get().getCurrentSelection();
+ if (selection == null || !(selection instanceof FileResource)) {
+ GSS.get().displayError("You have to select a file first");
+ return;
+ }
+ }
+
+ /**
+ * Create a download link for the respective menu item, if the currently
+ * selected object is a file.
+ *
+ * @param link a String array with two elements that is modified so that the
+ * first position contains the opening tag and the second one the
+ * closing tag
+ * @param forceDownload If true, link will be such that browser should ask for filename
+ * and save location
+ */
+ void createDownloadLink(String[] link, boolean forceDownload) {
+ String downloadURL = getDownloadURL();
+ if (!downloadURL.isEmpty()) {
+ link[0] = "<a id ='topMenu.file.download' class='hidden-link' href='" + downloadURL
+ + (forceDownload ? "&dl=1" : "") + "' target='_blank'>";
+ link[1] = "</a>";
+ }
+ }
+
+ public String getDownloadURL() {
+ GSS app = GSS.get();
+ Object selection = app.getCurrentSelection();
+ if (selection != null && selection instanceof FileResource) {
+ FileResource file = (FileResource) selection;
+ return getDownloadURL(file);
+ }
+ return "";
+ }
+
+ public String getDownloadURL(FileResource file) {
+ GSS app = GSS.get();
+ if (file != null) {
+ String dateString = RestCommand.getDate();
+ String resource = file.getUri().substring(app.getApiPath().length()-1,file.getUri().length());
+ String sig = app.getCurrentUserResource().getUsername()+" "+RestCommand.calculateSig("GET", dateString, resource, RestCommand.base64decode(app.getToken()));
+ return file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date="+URL.encodeComponent(dateString);
+ }
+ return "";
+ }
+
+ public MenuBar createMenu() {
+ contextMenu.clearItems();
+ contextMenu.setAutoOpen(false);
+ final Command downloadCmd = new Command() {
+
+ @Override
+ public void execute() {
+ hide();
+ preDownloadCheck();
+ }
+ };
+ //
+ RestResource selectedItem = GSS.get().getTreeView().getSelection();
+ boolean downloadVisible = GSS.get().getCurrentSelection() != null && GSS.get().getCurrentSelection() instanceof FileResource;
+ boolean propertiesVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource
+ //|| folders.isOthersShared(selectedItem) || selectedItem.getUserObject() instanceof GroupUserResource
+ || GSS.get().getCurrentSelection() instanceof List));
+ boolean newFolderVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource));
+ boolean uploadVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource));
+ if(newFolderVisible){
+ MenuItem newFolderItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.folderNew()).getHTML() + " New Folder</span>", true, new NewFolderCommand(this, images));
+ newFolderItem.getElement().setId("topMenu.file.newFolder");
+ contextMenu.addItem(newFolderItem);
+ }
+ if(uploadVisible){
+ MenuItem uploadItem = new MenuItem("<span id='topMenu.file.upload'>" + AbstractImagePrototype.create(images.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ contextMenu.addItem(uploadItem);
+ }
+ if (downloadVisible) {
+ String[] link = {"", ""};
+ createDownloadLink(link, false);
+
+ MenuItem downloadItem = new MenuItem("<span>" + link[0] + AbstractImagePrototype.create(images.download()).getHTML() + " Download" + link[1] + "</span>", true, downloadCmd);
+ contextMenu.addItem(downloadItem);
+
+ createDownloadLink(link, true);
+
+ MenuItem saveAsItem = new MenuItem("<span>" + link[0] + AbstractImagePrototype.create(images.download()).getHTML() + " Save As" + link[1] + "</span>", true, downloadCmd);
+ contextMenu.addItem(saveAsItem);
+ }
+ MenuItem emptyTrashItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.emptyTrash()).getHTML() + " Empty Trash</span>", true, new EmptyTrashCommand(this));
+ emptyTrashItem.getElement().setId("topMenu.file.emptyTrash");
+ contextMenu.addItem(emptyTrashItem);
+
+ MenuItem refreshItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ refreshItem.getElement().setId("topMenu.file.refresh");
+ contextMenu.addItem(refreshItem);
+
+ MenuItem sharingItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.sharing()).getHTML() + " Sharing</span>", true, new PropertiesCommand(this, images, 1));
+ sharingItem.getElement().setId("topMenu.file.sharing");
+ contextMenu.addItem(sharingItem)
+ .setVisible(propertiesVisible);
+
+ MenuItem propertiesItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.viewText()).getHTML() + " Properties</span>", true, new PropertiesCommand(this, images, 0));
+ propertiesItem.getElement().setId("topMenu.file.properties");
+ contextMenu.addItem(propertiesItem)
+ .setVisible(propertiesVisible);
+ return contextMenu;
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.rest.PostCommand;\r
+import org.gss_project.gss.web.client.rest.RestException;\r
+import org.gss_project.gss.web.client.rest.resource.FileResource;\r
+import org.gss_project.gss.web.client.rest.resource.GroupResource;\r
+import org.gss_project.gss.web.client.rest.resource.PermissionHolder;\r
+\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.event.dom.client.ChangeEvent;\r
+import com.google.gwt.event.dom.client.ChangeHandler;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.i18n.client.DateTimeFormat;\r
+import com.google.gwt.json.client.JSONArray;\r
+import com.google.gwt.json.client.JSONBoolean;\r
+import com.google.gwt.json.client.JSONObject;\r
+import com.google.gwt.json.client.JSONString;\r
+import com.google.gwt.resources.client.ClientBundle;\r
+import com.google.gwt.resources.client.ImageResource;\r
+import com.google.gwt.user.client.Command;\r
+import com.google.gwt.user.client.DeferredCommand;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.CheckBox;\r
+import com.google.gwt.user.client.ui.DecoratedTabPanel;\r
+import com.google.gwt.user.client.ui.DisclosurePanel;\r
+import com.google.gwt.user.client.ui.FlexTable;\r
+import com.google.gwt.user.client.ui.FlowPanel;\r
+import com.google.gwt.user.client.ui.FocusPanel;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.Label;\r
+import com.google.gwt.user.client.ui.TextBox;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'File properties' dialog box implementation.\r
+ *\r
+ * @author past\r
+ */\r
+public class FilePropertiesDialog extends AbstractPropertiesDialog {\r
+\r
+ final PermissionsList permList;\r
+\r
+ private CheckBox readForAll;\r
+\r
+ /**\r
+ * An image bundle for this widgets images.\r
+ */\r
+ public interface Images extends ClientBundle,MessagePanel.Images {\r
+\r
+ @Source("org/gss_project/gss/resources/edit_user.png")\r
+ ImageResource permUser();\r
+\r
+ @Source("org/gss_project/gss/resources/groupevent.png")\r
+ ImageResource permGroup();\r
+\r
+ @Source("org/gss_project/gss/resources/editdelete.png")\r
+ ImageResource delete();\r
+\r
+ @Source("org/gss_project/gss/resources/db_update.png")\r
+ ImageResource restore();\r
+\r
+ @Source("org/gss_project/gss/resources/folder_inbox.png")\r
+ ImageResource download();\r
+ }\r
+\r
+ /**\r
+ * The widget that holds the name of the file.\r
+ */\r
+ private TextBox name = new TextBox();\r
+\r
+ private final CheckBox versioned = new CheckBox();\r
+\r
+ final FileResource file;\r
+\r
+ private String userFullName;\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ *\r
+ * @param images the dialog's ImageBundle\r
+ * @param groups\r
+ * @param bodies\r
+ */\r
+ public FilePropertiesDialog(final Images images, final List<GroupResource> groups, List<FileResource> bodies, String _userFullName) {\r
+\r
+ // Set the dialog's caption.\r
+ setText("File properties");\r
+\r
+ file = (FileResource) GSS.get().getCurrentSelection();\r
+ userFullName = _userFullName;\r
+ permList = new PermissionsList(images, file.getPermissions(), file.getOwner());\r
+\r
+ GWT.log("FILE PERMISSIONS:"+file.getPermissions());\r
+ // Outer contains inner and buttons.\r
+ final VerticalPanel outer = new VerticalPanel();\r
+ final FocusPanel focusPanel = new FocusPanel(outer);\r
+ // Inner contains generalPanel and permPanel.\r
+ inner = new DecoratedTabPanel();\r
+ inner.setAnimationEnabled(true);\r
+ final VerticalPanel generalPanel = new VerticalPanel();\r
+ final VerticalPanel permPanel = new VerticalPanel();\r
+ final HorizontalPanel buttons = new HorizontalPanel();\r
+ final HorizontalPanel permButtons = new HorizontalPanel();\r
+ final HorizontalPanel permForAll = new HorizontalPanel();\r
+ final HorizontalPanel pathPanel = new HorizontalPanel();\r
+ final VerticalPanel verPanel = new VerticalPanel();\r
+ final HorizontalPanel vPanel = new HorizontalPanel();\r
+ final HorizontalPanel vPanel2 = new HorizontalPanel();\r
+\r
+ versioned.setValue(file.isVersioned());\r
+ versioned.getElement().setId("filePropertiesDialog.chechBox.versioned");\r
+ inner.add(generalPanel, "General");\r
+ inner.add(permPanel, "Sharing");\r
+ inner.add(verPanel, "Versions");\r
+ inner.selectTab(0);\r
+\r
+ final Label fileNameNote = new Label("Please note that slashes ('/') are not allowed in file names.", true);\r
+ fileNameNote.setVisible(false);\r
+ fileNameNote.setStylePrimaryName("gss-readForAllNote");\r
+\r
+ final FlexTable generalTable = new FlexTable();\r
+ generalTable.setText(0, 0, "Name");\r
+ generalTable.setText(1, 0, "Folder");\r
+ generalTable.setText(2, 0, "Owner");\r
+ generalTable.setText(3, 0, "Last modified");\r
+ generalTable.setText(4, 0, "Tags");\r
+ name.setWidth("100%");\r
+ name.setText(file.getName());\r
+ name.getElement().setId("filePropertiesDialog.textBox.name");\r
+ generalTable.setWidget(0, 1, name);\r
+ name.addChangeHandler(new ChangeHandler() {\r
+\r
+ @Override\r
+ public void onChange(ChangeEvent event) {\r
+ if(name.getText().contains("/"))\r
+ fileNameNote.setVisible(true);\r
+ else\r
+ fileNameNote.setVisible(false);\r
+\r
+ }\r
+ });\r
+\r
+ if(file.getFolderName() != null)\r
+ generalTable.setText(1, 1, file.getFolderName());\r
+ else\r
+ generalTable.setText(1, 1, "-");\r
+ generalTable.setWidget(0, 2, fileNameNote);\r
+ generalTable.setText(2, 1,userFullName);\r
+\r
+ final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");\r
+ generalTable.setText(3, 1, formatter.format(file.getModificationDate()));\r
+ // Get the tags.\r
+ StringBuffer tagsBuffer = new StringBuffer();\r
+ Iterator i = file.getTags().iterator();\r
+ while (i.hasNext()) {\r
+ String tag = (String) i.next();\r
+ tagsBuffer.append(tag).append(", ");\r
+ }\r
+ if (tagsBuffer.length() > 1)\r
+ tagsBuffer.delete(tagsBuffer.length() - 2, tagsBuffer.length() - 1);\r
+ initialTagText = tagsBuffer.toString();\r
+ tags.setWidth("100%");\r
+ tags.getElement().setId("filePropertiesDialog.textBox.tags");\r
+ tags.setText(initialTagText);\r
+ generalTable.setWidget(4, 1, tags);\r
+ generalTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(2, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(3, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(4, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(0, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(1, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(2, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(3, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(4, 1, "props-values");\r
+ generalTable.setCellSpacing(4);\r
+\r
+ // Create the 'OK' button, along with a listener that hides the dialog\r
+ // when the button is clicked.\r
+ final Button ok = new Button("OK", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ if(name.getText().contains("/"))\r
+ fileNameNote.setVisible(true);\r
+ else{\r
+ fileNameNote.setVisible(false);\r
+ accept();\r
+ closeDialog();\r
+ } \r
+ }\r
+ });\r
+ ok.getElement().setId("filePropertiesDialog.button.ok"); \r
+ buttons.add(ok);\r
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
+ // Create the 'Cancel' button, along with a listener that hides the\r
+ // dialog when the button is clicked.\r
+ final Button cancel = new Button("Cancel", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ closeDialog();\r
+ }\r
+ });\r
+ cancel.getElement().setId("filePropertiesDialog.button.cancel");\r
+ buttons.add(cancel);\r
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ buttons.setSpacing(8);\r
+ buttons.addStyleName("gss-TabPanelBottom");\r
+\r
+ generalPanel.add(generalTable);\r
+\r
+ // Asynchronously retrieve the tags defined by this user.\r
+ DeferredCommand.addCommand(new Command() {\r
+\r
+ @Override\r
+ public void execute() {\r
+ updateTags();\r
+ }\r
+ });\r
+\r
+ DisclosurePanel allTags = new DisclosurePanel("All tags");\r
+ allTagsContent = new FlowPanel();\r
+ allTagsContent.setWidth("100%");\r
+ allTags.setContent(allTagsContent);\r
+ generalPanel.add(allTags);\r
+ generalPanel.setSpacing(4);\r
+\r
+ final Button add = new Button("Add Group", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, false);\r
+ dlg.center();\r
+ }\r
+ });\r
+ add.getElement().setId("filePropertiesDialog.button.addGroup");\r
+ permButtons.add(add);\r
+ permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);\r
+\r
+ final Button addUser = new Button("Add User", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, true);\r
+ dlg.center();\r
+ }\r
+ });\r
+ add.getElement().setId("filePropertiesDialog.button.addUser");\r
+ permButtons.add(addUser);\r
+ permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);\r
+\r
+ permButtons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ permButtons.setSpacing(8);\r
+ permButtons.addStyleName("gss-TabPanelBottom");\r
+\r
+ final Label readForAllNote = new Label("When this option is enabled, the file will be readable" +\r
+ " by everyone. By checking this option, you are certifying that you have the right to " +\r
+ "distribute this file and that it does not violate the Terms of Use.", true);\r
+ readForAllNote.setVisible(false);\r
+ readForAllNote.setStylePrimaryName("gss-readForAllNote");\r
+\r
+ readForAll = new CheckBox();\r
+ readForAll.getElement().setId("filePropertiesDialog.checkBox.public");\r
+ readForAll.setValue(file.isReadForAll());\r
+ readForAll.addClickHandler(new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ readForAllNote.setVisible(readForAll.getValue());\r
+ }\r
+\r
+ });\r
+\r
+ permPanel.add(permList);\r
+ permPanel.add(permButtons);\r
+ // Only show the read for all permission if the user is the owner.\r
+ if (file.getOwner().equals(GSS.get().getCurrentUserResource().getUsername())) {\r
+ permForAll.add(new Label("Public"));\r
+ permForAll.add(readForAll);\r
+ permForAll.setSpacing(8);\r
+ permForAll.addStyleName("gss-TabPanelBottom");\r
+ permForAll.add(readForAllNote);\r
+ permPanel.add(permForAll);\r
+ }\r
+\r
+ TextBox path = new TextBox();\r
+ path.setWidth("100%");\r
+ path.addClickHandler(new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ GSS.enableIESelection();\r
+ ((TextBox) event.getSource()).selectAll();\r
+ GSS.preventIESelection();\r
+ }\r
+\r
+ });\r
+ path.setText(file.getUri());\r
+ path.getElement().setId("filePropertiesDialog.textBox.link");\r
+ path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
+ path.setWidth("100%");\r
+ path.setReadOnly(true);\r
+ pathPanel.setWidth("100%");\r
+ pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
+ pathPanel.add(new Label("Link"));\r
+ pathPanel.setSpacing(8);\r
+ pathPanel.addStyleName("gss-TabPanelBottom");\r
+ pathPanel.add(path);\r
+ permPanel.add(pathPanel);\r
+\r
+ VersionsList verList = new VersionsList(this, images, bodies);\r
+ verPanel.add(verList);\r
+\r
+ vPanel.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ vPanel.setSpacing(8);\r
+ vPanel.addStyleName("gss-TabPanelBottom");\r
+ vPanel.add(new Label("Versioned"));\r
+\r
+ vPanel.add(versioned);\r
+ verPanel.add(vPanel);\r
+ vPanel2.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ vPanel2.setSpacing(8);\r
+ vPanel2.addStyleName("gss-TabPanelBottom");\r
+ Button removeVersionsButton = new Button(AbstractImagePrototype.create(images.delete()).getHTML(), new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ ConfirmationDialog confirm = new ConfirmationDialog("Really " +\r
+ "remove all previous versions?", "Remove") {\r
+\r
+ @Override\r
+ public void cancel() {\r
+ }\r
+\r
+ @Override\r
+ public void confirm() {\r
+ FilePropertiesDialog.this.closeDialog();\r
+ removeAllOldVersions();\r
+ }\r
+\r
+ };\r
+ confirm.center();\r
+ }\r
+\r
+ });\r
+ HTML removeAllVersion = new HTML("<span>Remove all previous versions?</span>");\r
+ vPanel2.add(removeAllVersion);\r
+ vPanel2.add(removeVersionsButton);\r
+ verPanel.add(vPanel2);\r
+ if(!file.isVersioned())\r
+ vPanel2.setVisible(false);\r
+ outer.add(inner);\r
+ outer.add(buttons);\r
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
+ outer.addStyleName("gss-TabPanelBottom");\r
+\r
+ focusPanel.setFocus(true);\r
+ setWidget(outer);\r
+ }\r
+\r
+\r
+ /**\r
+ * Accepts any change and updates the file\r
+ *\r
+ */\r
+ @Override\r
+ protected void accept() {\r
+ String newFilename = null;\r
+ permList.updatePermissionsAccordingToInput();\r
+ Set<PermissionHolder> perms = permList.getPermissions();\r
+ JSONObject json = new JSONObject();\r
+ if (!name.getText().equals(file.getName())) {\r
+ newFilename = name.getText();\r
+ json.put("name", new JSONString(newFilename));\r
+ }\r
+ if (versioned.getValue() != file.isVersioned())\r
+ json.put("versioned", JSONBoolean.getInstance(versioned.getValue()));\r
+ //only update the read for all perm if the user is the owner\r
+ if (readForAll.getValue() != file.isReadForAll())\r
+ if (file.getOwner().equals(GSS.get().getCurrentUserResource().getUsername()))\r
+ json.put("readForAll", JSONBoolean.getInstance(readForAll.getValue()));\r
+ int i = 0;\r
+ if (permList.hasChanges()) {\r
+ GWT.log("Permissions change", null);\r
+ JSONArray perma = new JSONArray();\r
+\r
+ for (PermissionHolder p : perms) {\r
+ JSONObject po = new JSONObject();\r
+ if (p.getUser() != null)\r
+ po.put("user", new JSONString(p.getUser()));\r
+ if (p.getGroup() != null)\r
+ po.put("group", new JSONString(p.getGroup()));\r
+ po.put("read", JSONBoolean.getInstance(p.isRead()));\r
+ po.put("write", JSONBoolean.getInstance(p.isWrite()));\r
+ po.put("modifyACL", JSONBoolean.getInstance(p.isModifyACL()));\r
+ perma.set(i, po);\r
+ i++;\r
+ }\r
+ json.put("permissions", perma);\r
+ }\r
+ JSONArray taga = new JSONArray();\r
+ i = 0;\r
+ if (!tags.getText().equals(initialTagText)) {\r
+ String[] tagset = tags.getText().split(",");\r
+ for (String t : tagset) {\r
+ JSONString to = new JSONString(t);\r
+ taga.set(i, to);\r
+ i++;\r
+ }\r
+ json.put("tags", taga);\r
+ }\r
+ String jsonString = json.toString();\r
+ if(jsonString.equals("{}")){\r
+ GWT.log("NO CHANGES", null);\r
+ return;\r
+ }\r
+ final String newFilenameFinal = newFilename;\r
+ PostCommand cf = new PostCommand(file.getUri() + "?update=", jsonString, 200) {\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ GSS.get().getTreeView().refreshCurrentNode(false);\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ if (t instanceof RestException) {\r
+ int statusCode = ((RestException) t).getHttpStatusCode();\r
+ if (statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions");\r
+ else if (statusCode == 404)\r
+ GSS.get().displayError("User in permissions does not exist");\r
+ else if (statusCode == 409)\r
+ GSS.get().displayError("A file with the same name already exists");\r
+ else if (statusCode == 413)\r
+ GSS.get().displayError("Your quota has been exceeded");\r
+ else\r
+ GSS.get().displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());\r
+ } else\r
+ GSS.get().displayError("System error modifying file:" + t.getMessage());\r
+ }\r
+\r
+ };\r
+ DeferredCommand.addCommand(cf);\r
+\r
+ }\r
+\r
+ private void removeAllOldVersions() {\r
+ JSONObject json = new JSONObject();\r
+ json.put("versioned", JSONBoolean.getInstance(false));\r
+ GWT.log(json.toString(), null);\r
+ PostCommand cf = new PostCommand(file.getUri() + "?update=", json.toString(), 200) {\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ toggleVersioned(true);\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ if (t instanceof RestException) {\r
+ int statusCode = ((RestException) t).getHttpStatusCode();\r
+ if (statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions");\r
+ else if (statusCode == 404)\r
+ GSS.get().displayError("User in permissions does not exist");\r
+ else if (statusCode == 409)\r
+ GSS.get().displayError("A folder with the same name already exists");\r
+ else if (statusCode == 413)\r
+ GSS.get().displayError("Your quota has been exceeded");\r
+ else\r
+ GSS.get().displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());\r
+ } else\r
+ GSS.get().displayError("System error moifying file:" + t.getMessage());\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(cf);\r
+ }\r
+\r
+ private void toggleVersioned(boolean versionedValue) {\r
+ JSONObject json = new JSONObject();\r
+ json.put("versioned", JSONBoolean.getInstance(versionedValue));\r
+ GWT.log(json.toString(), null);\r
+ PostCommand cf = new PostCommand(file.getUri() + "?update=", json.toString(), 200) {\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ GSS.get().getTreeView().refreshCurrentNode(false);\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ if (t instanceof RestException) {\r
+ int statusCode = ((RestException) t).getHttpStatusCode();\r
+ if (statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions");\r
+ else if (statusCode == 404)\r
+ GSS.get().displayError("User in permissions does not exist");\r
+ else if (statusCode == 409)\r
+ GSS.get().displayError("A folder with the same name already exists");\r
+ else if (statusCode == 413)\r
+ GSS.get().displayError("Your quota has been exceeded");\r
+ else\r
+ GSS.get().displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());\r
+ } else\r
+ GSS.get().displayError("System error moifying file:" + t.getMessage());\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(cf);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Grid;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
+
+
+/**
+ * @author kman
+ *
+ */
+public class FileTable extends Grid{
+
+ /**
+ *
+ */
+ public FileTable() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param rows
+ * @param columns
+ */
+ public FileTable(int rows, int columns) {
+ super(rows, columns);
+ // TODO Auto-generated constructor stub
+ }
+
+ public int getRowForEvent2(Event event) {
+ Element td = getEventTargetCell(event);
+ if (td == null)
+ return -1;
+
+ Element tr = DOM.getParent(td);
+ Element body = DOM.getParent(tr);
+ int row = DOM.getChildIndex(body, tr);
+ return row;
+ }
+
+ public static void copyRow(FileTable sourceTable, FileTable targetTable, int sourceRow, int targetRow) {
+ targetTable.insertRow(targetRow);
+ for (int col = 0; col < sourceTable.getCellCount(sourceRow); col++) {
+ HTML html = new HTML(sourceTable.getHTML(sourceRow, col));
+ targetTable.setWidget(targetRow, col, html);
+ }
+ copyRowStyle(sourceTable, targetTable, sourceRow, targetRow);
+ }
+
+ private static void copyRowStyle(FileTable sourceTable, FileTable targetTable, int sourceRow, int targetRow) {
+ String rowStyle = sourceTable.getRowFormatter().getStyleName(sourceRow);
+ targetTable.getRowFormatter().setStyleName(targetRow, rowStyle);
+ }
+
+ public static int getWidgetRow(Widget widget, FileTable table) {
+ for (int row = 0; row < table.getRowCount(); row++)
+ for (int col = 0; col < table.getCellCount(row); col++) {
+ Widget w = table.getWidget(row, col);
+ if (w == widget)
+ return row;
+ }
+ throw new RuntimeException("Unable to determine widget row");
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+import org.gss_project.gss.web.client.rest.resource.UploadStatusResource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.FileUpload;
+import com.google.gwt.user.client.ui.FormPanel;
+import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
+import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
+import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
+import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;
+import com.google.gwt.user.client.ui.Grid;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.Hidden;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+/**
+ * The 'File upload' dialog box implementation.
+ */
+public class FileUploadDialog extends DialogBox implements Updateable {
+
+ protected int prgBarInterval = 1500;
+
+ private ProgressBar progressBar;
+
+ protected RepeatingTimer repeater = new RepeatingTimer(this, prgBarInterval);
+
+ public static final boolean DONE = true;
+
+ /**
+ * The Form element that performs the file upload.
+ */
+ private final FormPanel form = new FormPanel();
+
+ private final FileUpload upload = new FileUpload();
+
+ protected final Label filenameLabel = new Label("");
+
+ protected List<FileResource> files;
+
+ protected boolean cancelEvent = false;
+
+ protected String fileNameToUse;
+
+ protected FolderResource folder;
+
+ /**
+ * The widget's constructor.
+ */
+ public FileUploadDialog() {
+ // Set the dialog's caption.
+ setText("File upload");
+ setAnimationEnabled(true);
+ // Since we're going to add a FileUpload widget, we'll need to set the
+ // form to use the POST method, and multipart MIME encoding.
+ form.setEncoding(FormPanel.ENCODING_MULTIPART);
+ form.setMethod(FormPanel.METHOD_POST);
+
+ // Create a panel to hold all of the form widgets.
+ VerticalPanel panel = new VerticalPanel();
+ form.setWidget(panel);
+ final HTML info = new HTML("You may select a file to upload. Install" +
+ " <a href='http://gears.google.com/' target='_blank'>Google " +
+ "Gears</a><br> for uploading multiple files simultaneously.");
+ info.addStyleName("gss-uploadNote");
+ panel.add(info);
+ final Hidden date = new Hidden("Date", "");
+ panel.add(date);
+ final Hidden auth = new Hidden("Authorization", "");
+ panel.add(auth);
+ // Add an informative label with the folder name.
+ Object selection = GSS.get().getTreeView().getSelection();
+ folder = ((RestResourceWrapper) selection).getResource();
+ upload.setName("file");
+ filenameLabel.setText("");
+ filenameLabel.setVisible(false);
+ filenameLabel.setStyleName("props-labels");
+ HorizontalPanel fileUloadPanel = new HorizontalPanel();
+ fileUloadPanel.add(filenameLabel);
+ fileUloadPanel.add(upload);
+ upload.getElement().setId("fileUploadDiallog.uploadPanel");
+ Grid generalTable = new Grid(2, 2);
+ generalTable.setText(0, 0, "Folder");
+ generalTable.setText(1, 0, "File");
+ generalTable.setText(0, 1, folder.getName());
+ generalTable.setWidget(1, 1, fileUloadPanel);
+ generalTable.getCellFormatter().setStyleName(0, 0, "props-labels");
+ generalTable.getCellFormatter().setStyleName(1, 0, "props-labels");
+ generalTable.getCellFormatter().setStyleName(0, 1, "props-values");
+ generalTable.getCellFormatter().setStyleName(1, 1, "props-values");
+ generalTable.setCellSpacing(4);
+
+ panel.add(generalTable);
+
+ // Create a panel to hold the buttons.
+ HorizontalPanel buttons = new HorizontalPanel();
+
+ // Create the 'upload' button, along with a listener that submits the
+ // form.
+ final Button submit = new Button("Upload", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ prepareAndSubmit();
+ }
+ });
+ submit.getElement().setId("fileUploadDialog.button.upload");
+ buttons.add(submit);
+ buttons.setCellHorizontalAlignment(submit, HasHorizontalAlignment.ALIGN_CENTER);
+ // Create the 'Cancel' button, along with a listener that hides the
+ // dialog when the button is clicked.
+ final Button cancel = new Button("Cancel", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ repeater.finish();
+ hide();
+ }
+ });
+ cancel.getElement().setId("fileUploadDialog.button.cancel");
+ buttons.add(cancel);
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
+ buttons.setSpacing(8);
+ buttons.addStyleName("gss-DialogBox");
+
+ // Add an event handler to the form.
+ form.addSubmitHandler(new SubmitHandler() {
+
+ @Override
+ public void onSubmit(SubmitEvent event) {
+ GSS app = GSS.get();
+ // This event is fired just before the form is submitted. We can
+ // take this opportunity to perform validation.
+ if (upload.getFilename().length() == 0) {
+ app.displayError("You must select a file!");
+ event.cancel();
+ hide();
+ } else {
+
+ canContinue();
+ GWT.log("Cancel:" + cancelEvent, null);
+ if (cancelEvent) {
+ cancelEvent = false;
+ app.displayError("The specified file name already exists in this folder");
+ event.cancel();
+ hide();
+ } else {
+
+ fileNameToUse = getFilename(upload.getFilename());
+ String apath;
+ FileResource selectedFile = getFileForName(fileNameToUse);
+ if (selectedFile == null ) {
+ //we are going to create a file
+ apath = folder.getUri();
+ if (!apath.endsWith("/"))
+ apath = apath + "/";
+ apath = apath + encodeComponent(fileNameToUse);
+ } else
+ apath = selectedFile.getUri();
+ form.setAction(apath);
+ String dateString = RestCommand.getDate();
+ String resource = apath.substring(app.getApiPath().length() - 1, apath.length());
+ String sig = RestCommand.calculateSig("POST", dateString, resource, RestCommand.base64decode(app.getToken()));
+ date.setValue(dateString);
+ auth.setValue(app.getCurrentUserResource().getUsername() + " " + sig);
+ GWT.log("FolderPATH:" + folder.getUri(), null);
+ submit.setEnabled(false);
+ upload.setVisible(false);
+ filenameLabel.setText(fileNameToUse);
+ filenameLabel.setVisible(true);
+ repeater.start();
+ progressBar.setVisible(true);
+ }
+ }
+
+ }
+ });
+ form.addSubmitCompleteHandler(new SubmitCompleteHandler() {
+
+ @Override
+ public void onSubmitComplete(SubmitCompleteEvent event) {
+ // When the form submission is successfully completed, this
+ // event is fired. Assuming the service returned a response
+ // of type text/html, we can get the result text here (see
+ // the FormPanel documentation for further explanation).
+ String results = event.getResults();
+
+ // Unfortunately the results are never empty, even in
+ // the absense of errors, so we have to check for '<pre></pre>'.
+ if (!results.equalsIgnoreCase("<pre></pre>")) {
+ GWT.log(results, null);
+ GSS.get().displayError(results);
+ }
+ progressBar.setProgress(100);
+ cancelUpload();
+ GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());
+ GSS.get().getStatusPanel().updateStats();
+
+ }
+ });
+
+
+ panel.add(buttons);
+ progressBar = new ProgressBar(50, ProgressBar.SHOW_TIME_REMAINING);
+ panel.add(progressBar);
+ progressBar.setVisible(false);
+ panel.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
+ panel.setCellHorizontalAlignment(progressBar, HasHorizontalAlignment.ALIGN_CENTER);
+ panel.addStyleName("gss-DialogBox");
+ addStyleName("gss-DialogBox");
+ setWidget(form);
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when either
+ // enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ prepareAndSubmit();
+ break;
+ case KeyCodes.KEY_ESCAPE:
+ cancelUpload();
+ break;
+ }
+ }
+
+
+
+ /**
+ * Cancels the file upload.
+ */
+ private void cancelUpload() {
+ repeater.finish();
+ hide();
+ }
+
+ /**
+ * Make any last minute checks and start the upload.
+ */
+ public void prepareAndSubmit() {
+ final String fname = getFilename(upload.getFilename());
+ if (getFileForName(fname) == null) {
+ //we are going to create a file, so we check to see if there is a trashed file with the same name
+ FileResource same = null;
+ for (FileResource fres : folder.getFiles())
+ if (fres.isDeleted() && fres.getName().equals(fname))
+ same = fres;
+ if (same == null)
+ form.submit();
+ else {
+ final FileResource sameFile = same;
+ GWT.log("Same deleted file", null);
+ ConfirmationDialog confirm = new ConfirmationDialog("A file with " +
+ "the same name exists in the trash. If you continue,<br/>the trashed " +
+ "file '" + fname + "' will be renamed automatically for you.", "Continue") {
+
+ @Override
+ public void cancel() {
+ FileUploadDialog.this.hide();
+ }
+
+ @Override
+ public void confirm() {
+ updateTrashedFile(getBackupFilename(fname), sameFile);
+ }
+
+ };
+ confirm.center();
+ }
+ }
+ else {
+ // We are going to update an existing file, so show a confirmation dialog.
+ ConfirmationDialog confirm = new ConfirmationDialog("Are you sure " +
+ "you want to update " + fname + "?", "Update") {
+
+ @Override
+ public void cancel() {
+ FileUploadDialog.this.hide();
+ }
+
+ @Override
+ public void confirm() {
+ form.submit();
+ }
+
+ };
+ confirm.center();
+ }
+ }
+
+ /**
+ * Returns the file name from a potential full path argument. Apparently IE
+ * insists on sending the full path name of a file when uploading, forcing
+ * us to trim the extra path info. Since this is only observed on Windows we
+ * get to check for a single path separator value.
+ *
+ * @param name the potentially full path name of a file
+ * @return the file name without extra path information
+ */
+ protected String getFilename(String name) {
+ int pathSepIndex = name.lastIndexOf("\\");
+ if (pathSepIndex == -1) {
+ pathSepIndex = name.lastIndexOf("/");
+ if (pathSepIndex == -1)
+ return name;
+ }
+ return name.substring(pathSepIndex + 1);
+ }
+
+ /**
+ * Check whether the file name exists in selected folder.
+ *
+ * @return
+ */
+ private boolean canContinue() {
+ if (files == null)
+ return false;
+ String fileName = getFilename(upload.getFilename());
+ if (getFileForName(fileName) == null) {
+ // For file creation, check to see if the file already exists.
+ GWT.log("filename to upload:" + fileName, null);
+ for (FileResource dto : files) {
+ GWT.log("Check:" + dto.getName() + "/" + fileName, null);
+ if (!dto.isDeleted() && dto.getName().equals(fileName)) {
+ cancelEvent = true;
+ return true;
+ }
+ }
+ }
+ return true;
+ }
+
+ class RepeatingTimer extends Timer {
+
+ private Updateable updateable;
+
+ private int interval = 1500;
+
+ private boolean running = true;
+
+ RepeatingTimer(Updateable _updateable, int _interval) {
+ updateable = _updateable;
+ interval = _interval;
+ }
+
+ @Override
+ public void run() {
+ updateable.update();
+ }
+
+ public void start() {
+ running = true;
+
+ scheduleRepeating(interval);
+ }
+
+ public void finish() {
+ running = false;
+ cancel();
+ }
+
+ public int getInterval() {
+ return interval;
+ }
+
+ public void setInterval(int anInterval) {
+ if (interval != anInterval) {
+ interval = anInterval;
+ if (running) {
+ finish();
+ start();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void update() {
+ String apath = folder.getUri();
+ if (!apath.endsWith("/"))
+ apath = apath + "/";
+ apath = apath + encodeComponent(fileNameToUse) + "?progress=" + encodeComponent(fileNameToUse);
+ GetCommand eg = new GetCommand<UploadStatusResource>(UploadStatusResource.class, apath, false, null) {
+
+ @Override
+ public void onComplete() {
+ UploadStatusResource res = getResult();
+ progressBar.setProgress(res.percent());
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ }
+
+ };
+ DeferredCommand.addCommand(eg);
+ }
+
+ protected String getBackupFilename(String filename) {
+ List<FileResource> filesInSameFolder = new ArrayList<FileResource>();
+ for (FileResource deleted : folder.getFiles())
+ if (deleted.isDeleted())
+ filesInSameFolder.add(deleted);
+ int i = 1;
+ for (FileResource same : filesInSameFolder)
+ if (same.getName().startsWith(filename)) {
+ String toCheck = same.getName().substring(filename.length(), same.getName().length());
+ if (toCheck.startsWith(" ")) {
+ int test = -1;
+ try {
+ test = Integer.valueOf(toCheck.replace(" ", ""));
+ } catch (NumberFormatException e) {
+ // Do nothing since string is not a number.
+ }
+ if (test >= i)
+ i = test + 1;
+ }
+ }
+
+ return filename + " " + i;
+ }
+
+ /**
+ * Rename the conflicting trashed file with the supplied new name.
+ */
+ private void updateTrashedFile(String newName, FileResource trashedFile) {
+ JSONObject json = new JSONObject();
+ json.put("name", new JSONString(newName));
+ PostCommand cf = new PostCommand(trashedFile.getUri() + "?update=", json.toString(), 200) {
+
+ @Override
+ public void onComplete() {
+ form.submit();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GSS app = GSS.get();
+ GWT.log("", t);
+ if (t instanceof RestException) {
+ int statusCode = ((RestException) t).getHttpStatusCode();
+ if (statusCode == 405)
+ app.displayError("You don't have the necessary permissions");
+ else if (statusCode == 404)
+ app.displayError("User in permissions does not exist");
+ else if (statusCode == 409)
+ app.displayError("A file with the same name already exists");
+ else if (statusCode == 413)
+ app.displayError("Your quota has been exceeded");
+ else
+ app.displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());
+ } else
+ app.displayError("System error modifying file:" + t.getMessage());
+ }
+
+ };
+ DeferredCommand.addCommand(cf);
+ }
+
+ protected FileResource getFileForName(String name){
+ for (FileResource f : folder.getFiles())
+ if (!f.isDeleted() && f.getName().equals(name))
+ return f;
+ return null;
+ }
+
+
+ /**
+ * Same as URL.encodeComponent, but also
+ * encode apostrophe since browsers aren't consistent about it
+ * (FF encodes, IE does not).
+ */
+ private String encodeComponent(String decodedURLComponent) {
+ String retv = URL.encodeComponent(decodedURLComponent);
+ retv = retv.replaceAll("'", "%27");
+ return retv;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFiles the files to set
+ */
+ public void setFiles(List<FileResource> newFiles) {
+ files = newFiles;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.gears.client.Factory;
+import com.google.gwt.gears.client.desktop.Desktop;
+import com.google.gwt.gears.client.desktop.File;
+import com.google.gwt.gears.client.desktop.OpenFilesHandler;
+import com.google.gwt.gears.client.httprequest.HttpRequest;
+import com.google.gwt.gears.client.httprequest.ProgressEvent;
+import com.google.gwt.gears.client.httprequest.ProgressHandler;
+import com.google.gwt.gears.client.httprequest.RequestCallback;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+/**
+ * The 'File upload' dialog box implementation with Google Gears support.
+ */
+public class FileUploadGearsDialog extends FileUploadDialog implements Updateable {
+
+ protected final Factory factory = Factory.getInstance();
+
+ /**
+ * The array of files to upload.
+ */
+ private File[] fileObjects;
+
+ /**
+ * A list of files to upload, created from files array. Used to signal
+ * finished state when empty.
+ */
+ protected List<File> selectedFiles = new ArrayList<File>();
+
+ /**
+ * The list of progress bars for individual files.
+ */
+ protected List<ProgressBar> progressBars = new ArrayList<ProgressBar>();
+
+ private Button browse;
+
+ private Button submit;
+
+ private FlexTable generalTable;
+
+ private Map<String, FileResource> toRename;
+
+ protected List<HttpRequest> requests = new ArrayList<HttpRequest>();
+
+ private boolean canContinue = true;
+
+ /**
+ * The widget's constructor.
+ */
+ public FileUploadGearsDialog() {
+ // Set the dialog's caption.
+ setText("File upload");
+ setAnimationEnabled(true);
+ // Create a panel to hold all of the dialog widgets.
+ VerticalPanel panel = new VerticalPanel();
+ final HTML info = new HTML("You may select one or more files to upload.");
+ info.addStyleName("gss-uploadNote");
+ panel.add(info);
+ // Add an informative label with the folder name.
+ Object selection = GSS.get().getTreeView().getSelection();
+ folder = ((RestResourceWrapper) selection).getResource();
+
+ browse = new Button("Browse...");
+
+ HorizontalPanel fileUploadPanel = new HorizontalPanel();
+ fileUploadPanel.add(browse);
+
+ generalTable = new FlexTable();
+ generalTable.setText(0, 0, "Folder");
+ generalTable.setText(1, 0, "File");
+ generalTable.setText(0, 1, folder.getName());
+ generalTable.setWidget(1, 1, fileUploadPanel);
+ generalTable.getCellFormatter().setStyleName(0, 0, "props-labels");
+ generalTable.getCellFormatter().setStyleName(1, 0, "props-labels");
+ generalTable.getCellFormatter().setStyleName(0, 1, "props-values");
+ generalTable.getCellFormatter().setStyleName(1, 1, "props-values");
+ generalTable.setCellSpacing(4);
+
+ panel.add(generalTable);
+
+ // Create a panel to hold the buttons.
+ HorizontalPanel buttons = new HorizontalPanel();
+
+ submit = new Button("Upload");
+ submit.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ prepareAndSubmit();
+ }
+ });
+ submit.setEnabled(false);
+ buttons.add(submit);
+ buttons.setCellHorizontalAlignment(submit, HasHorizontalAlignment.ALIGN_CENTER);
+ // Create the 'Cancel' button, along with a listener that hides the
+ // dialog when the button is clicked.
+ Button cancel = new Button("Cancel", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ canContinue = false;
+ cancelUpload();
+ GSS.get().showFileList(true);
+ }
+ });
+ buttons.add(cancel);
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
+ buttons.setSpacing(8);
+ buttons.addStyleName("gss-DialogBox");
+
+ browse.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ Desktop desktop = factory.createDesktop();
+ desktop.openFiles(new OpenFilesHandler() {
+
+ @Override
+ public void onOpenFiles(OpenFilesEvent ofevent) {
+ fileObjects = ofevent.getFiles();
+ selectedFiles.addAll(Arrays.asList(fileObjects));
+ for (int i = 0; i< selectedFiles.size(); i++) {
+ generalTable.setText(i+1, 0, "File");
+ generalTable.setText(i+1, 1, selectedFiles.get(i).getName());
+ ProgressBar progress = new ProgressBar(20, 0);
+ generalTable.setWidget(i+1, 2, progress);
+ progressBars.add(progress);
+ generalTable.getCellFormatter().setStyleName(i+1, 0, "props-labels");
+ generalTable.getCellFormatter().setStyleName(i+1, 1, "props-values");
+ }
+ submit.setEnabled(true);
+ }
+ });
+ }
+ });
+
+ panel.add(buttons);
+ panel.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
+ panel.addStyleName("gss-DialogBox");
+ addStyleName("gss-DialogBox");
+ setWidget(panel);
+ }
+
+ /**
+ * Cancels the file upload.
+ */
+ private void cancelUpload() {
+ for (HttpRequest request: requests)
+ request.abort();
+ hide();
+ }
+
+ /**
+ * Check whether the specified file name exists in the selected folder.
+ */
+ private boolean canContinue(File file) {
+ String fileName = getFilename(file.getName());
+ if (getFileForName(fileName) == null)
+ // For file creation, check to see if the file already exists.
+ for (FileResource fileRes : files)
+ if (!fileRes.isDeleted() && fileRes.getName().equals(fileName))
+ return false;
+ return true;
+ }
+
+ @Override
+ public void prepareAndSubmit() {
+ GSS app = GSS.get();
+ if (selectedFiles.size() == 0) {
+ app.displayError("You must select a file!");
+ hide();
+ return;
+ }
+ for (File file: selectedFiles)
+ if (!canContinue(file)) {
+ app.displayError("The file name " + file.getName() +
+ " already exists in this folder");
+ hide();
+ return;
+ }
+ submit.setEnabled(false);
+ browse.setVisible(false);
+ List<String> toUpdate = new ArrayList<String>();
+ toRename = new HashMap<String, FileResource>();
+ for (File file: selectedFiles) {
+ String fname = getFilename(file.getName());
+ if (getFileForName(fname) == null) {
+ // We are going to create a file, so we check to see if there is a
+ // trashed file with the same name.
+ FileResource same = null;
+ for (FileResource fres : folder.getFiles())
+ if (fres.isDeleted() && fres.getName().equals(fname))
+ same = fres;
+ // In that case add it to the list of files to rename.
+ if (same != null)
+ toRename.put(getBackupFilename(fname), same);
+ } else
+ // If we are updating a file add it to the list of files to update.
+ toUpdate.add(fname);
+ }
+
+ if (!toUpdate.isEmpty()) {
+ StringBuffer sb = new StringBuffer();
+ for (String name: toUpdate)
+ sb.append(name).append("<br/>");
+ // We are going to update existing files, so show a confirmation dialog.
+ ConfirmationDialog confirm = new ConfirmationDialog("Are you sure " +
+ "you want to update the following files?<br/><i>" + sb +
+ "</i>", "Update") {
+
+ @Override
+ public void cancel() {
+ hide();
+ }
+
+ @Override
+ public void confirm() {
+ confirmRename();
+ }
+
+ };
+ confirm.center();
+ } else
+ confirmRename();
+ }
+
+ /**
+ * Confirm the renames of synonymous files already in the trash.
+ */
+ private void confirmRename() {
+ if (!toRename.isEmpty()) {
+ StringBuffer sb = new StringBuffer();
+ for (FileResource file: toRename.values())
+ sb.append(file.getName()).append("<br/>");
+ ConfirmationDialog confirm = new ConfirmationDialog("Files " +
+ "with the following names already exist in the trash. If" +
+ " you continue,<br/>the trashed files will be renamed " +
+ "automatically for you:<br/><i>" + sb + "</i>", "Continue") {
+
+ @Override
+ public void cancel() {
+ hide();
+ }
+
+ @Override
+ public void confirm() {
+ updateTrashedFiles();
+ }
+
+ };
+ confirm.center();
+ } else
+ uploadFiles();
+ }
+
+ /**
+ * Rename the conflicting trashed files with the supplied new names.
+ */
+ private void updateTrashedFiles() {
+ for (final String name: toRename.keySet()) {
+ JSONObject json = new JSONObject();
+ json.put("name", new JSONString(name));
+ PostCommand cf = new PostCommand(toRename.get(name).getUri() + "?update=", json.toString(), 200) {
+
+ @Override
+ public void onComplete() {
+ toRename.remove(name);
+ uploadFiles();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GSS app = GSS.get();
+ GWT.log("", t);
+ if (t instanceof RestException) {
+ int statusCode = ((RestException) t).getHttpStatusCode();
+ if (statusCode == 405)
+ app.displayError("You don't have the necessary permissions");
+ else if (statusCode == 404)
+ app.displayError("User in permissions does not exist");
+ else if (statusCode == 409)
+ app.displayError("A file with the same name already exists");
+ else if (statusCode == 413)
+ app.displayError("Your quota has been exceeded");
+ else
+ app.displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());
+ } else
+ app.displayError("System error modifying file:" + t.getMessage());
+ }
+
+ };
+ DeferredCommand.addCommand(cf);
+ }
+ }
+
+ /**
+ * Checks if the renaming step for already trashed files is complete and
+ * starts file uploads.
+ */
+ private void uploadFiles() {
+ if (!toRename.isEmpty()) return;
+ if (canContinue){
+ doSend(selectedFiles);
+ }
+ }
+
+ /**
+ * Perform the HTTP request to upload the specified file.
+ */
+ protected void doSend(final List<File> filesRemaining) {
+ final GSS app = GSS.get();
+ HttpRequest request = factory.createHttpRequest();
+ requests.add(request);
+ String method = "PUT";
+
+ String path;
+ final String filename = getFilename(filesRemaining.get(0).getName());
+ path = folder.getUri();
+ if (!path.endsWith("/"))
+ path = path + "/";
+ path = path + encode(filename);
+
+ String token = app.getToken();
+ String resource = path.substring(app.getApiPath().length()-1, path.length());
+ String date = RestCommand.getDate();
+ String sig = RestCommand.calculateSig(method, date, resource, RestCommand.base64decode(token));
+ request.open(method, path);
+ request.setRequestHeader("X-GSS-Date", date);
+ request.setRequestHeader("Authorization", app.getCurrentUserResource().getUsername() + " " + sig);
+ request.setRequestHeader("Accept", "application/json; charset=utf-8");
+ request.setCallback(new RequestCallback() {
+ @Override
+ public void onResponseReceived(HttpRequest req) {
+ int state = req.getReadyState();
+ if (state != 4) return;
+ switch(req.getStatus()) {
+ case 201: // Created falls through to updated.
+ case 204:
+ filesRemaining.remove(0);
+ if(filesRemaining.isEmpty()){
+ finish();
+ break;
+ }
+ doSend(filesRemaining);
+ break;
+ case 403:
+ SessionExpiredDialog dlg = new SessionExpiredDialog();
+ dlg.center();
+ break;
+ case 405:
+ app.displayError("You don't have permission to " +
+ "upload file " + filename);
+ break;
+ case 409:
+ app.displayError("A folder with the name " + filename +
+ " already exists at this level");
+ break;
+ case 413:
+ app.displayError("There is not enough free space " +
+ "available for uploading " + filename);
+ break;
+ default:
+ app.displayError("Error uploading file " + filename +
+ ": " + req.getStatus());
+ }
+ }
+ });
+ request.getUpload().setProgressHandler(new ProgressHandler() {
+ @Override
+ public void onProgress(ProgressEvent event) {
+ double pcnt = (double) event.getLoaded() / event.getTotal();
+ progressBars.get(0).setProgress((int) Math.floor(pcnt * 100));
+ if(pcnt*100 == 100)
+ progressBars.remove(0);
+ }
+ });
+ request.send(filesRemaining.get(0).getBlob());
+ }
+
+ /**
+ * Perform the final actions after the files are uploaded.
+ */
+ protected void finish() {
+ hide();
+ //GSS.get().showFileList(true);
+ GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());//showFileList(true);
+ GSS.get().getStatusPanel().updateStats();
+ }
+
+ /**
+ * Same as URL.encode, but also encode apostrophe since browsers aren't
+ * consistent about it (FF encodes, IE does not).
+ */
+ protected String encode(String decodedURL) {
+ String retv = decodedURL.replaceAll("@", "_"); // Replace bad character
+ retv = URL.encodeComponent(retv);
+ retv = retv.replaceAll("'", "%27");
+ return retv;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import java.util.List;
+
+import org.gss_project.gss.web.client.rest.RestCommand;
+
+import com.google.gwt.gears.client.desktop.File;
+import com.google.gwt.gears.client.httprequest.HttpRequest;
+import com.google.gwt.gears.client.httprequest.ProgressEvent;
+import com.google.gwt.gears.client.httprequest.ProgressHandler;
+import com.google.gwt.gears.client.httprequest.RequestCallback;
+
+/**
+ * The 'File upload' dialog box implementation with Google Gears support
+ * for IE.
+ */
+public class FileUploadGearsIEDialog extends FileUploadGearsDialog implements Updateable {
+
+ /**
+ * Perform the HTTP request to upload the specified file.
+ */
+ @Override
+ protected void doSend(final List<File> filesRemaining) {
+ final GSS app = GSS.get();
+ HttpRequest request = factory.createHttpRequest();
+ requests.add(request);
+ String method = "POST";
+
+ String path;
+ final String filename = getFilename(filesRemaining.get(0).getName());
+ path = folder.getUri();
+ if (!path.endsWith("/"))
+ path = path + "/";
+ path = path + encode(filename);
+
+ String token = app.getToken();
+ String resource = path.substring(app.getApiPath().length()-1, path.length());
+ String date = RestCommand.getDate();
+ String sig = RestCommand.calculateSig(method, date, resource, RestCommand.base64decode(token));
+ request.open(method, path);
+ request.setRequestHeader("X-GSS-Date", date);
+ request.setRequestHeader("Authorization", app.getCurrentUserResource().getUsername() + " " + sig);
+ request.setRequestHeader("Accept", "application/json; charset=utf-8");
+ request.setCallback(new RequestCallback() {
+ @Override
+ public void onResponseReceived(HttpRequest req) {
+ // XXX: No error checking, since IE throws an Internal Error
+ // when accessing req.getStatus().
+ filesRemaining.remove(0);
+ if(filesRemaining.isEmpty()){
+ finish();
+ }
+ doSend(filesRemaining);
+ }
+ });
+ request.getUpload().setProgressHandler(new ProgressHandler() {
+ @Override
+ public void onProgress(ProgressEvent event) {
+ double pcnt = (double) event.getLoaded() / event.getTotal();
+ progressBars.get(0).setProgress((int) Math.floor(pcnt * 100));
+ if(pcnt*100 == 100)
+ progressBars.remove(0);
+ }
+ });
+ request.send(filesRemaining.get(0).getBlob());
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.components.TristateCheckBox;\r
+import org.gss_project.gss.web.client.rest.MultiplePostCommand;\r
+import org.gss_project.gss.web.client.rest.RestException;\r
+import org.gss_project.gss.web.client.rest.resource.FileResource;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.FocusEvent;\r
+import com.google.gwt.event.dom.client.FocusHandler;\r
+import com.google.gwt.json.client.JSONArray;\r
+import com.google.gwt.json.client.JSONBoolean;\r
+import com.google.gwt.json.client.JSONObject;\r
+import com.google.gwt.json.client.JSONString;\r
+import com.google.gwt.user.client.Command;\r
+import com.google.gwt.user.client.DeferredCommand;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.DecoratedTabPanel;\r
+import com.google.gwt.user.client.ui.DisclosurePanel;\r
+import com.google.gwt.user.client.ui.FlexTable;\r
+import com.google.gwt.user.client.ui.FlowPanel;\r
+import com.google.gwt.user.client.ui.FocusPanel;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.Label;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'Multiple file properties' dialog box implementation.\r
+ *\r
+ * @author droutsis\r
+ */\r
+public class FilesPropertiesDialog extends AbstractPropertiesDialog {\r
+\r
+ private final TristateCheckBox versionedCheck;\r
+\r
+ private final List<FileResource> files;\r
+\r
+ private Boolean initialVersioned;\r
+\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ *\r
+ * @param _files\r
+ */\r
+ public FilesPropertiesDialog(final List<FileResource> _files) {\r
+ super();\r
+\r
+ files = _files;\r
+ int versionedNum = 0;\r
+ for (FileResource fr : files)\r
+ if (fr.isVersioned()) versionedNum++;\r
+ Boolean versioned = null;\r
+ if (versionedNum==0) versioned = false;\r
+ if (versionedNum==files.size()) versioned = true;\r
+ initialVersioned = versioned;\r
+ versionedCheck = new TristateCheckBox(versioned);\r
+\r
+ // Set the dialog's caption.\r
+ setText("Files properties");\r
+\r
+ // Outer contains inner and buttons.\r
+ final VerticalPanel outer = new VerticalPanel();\r
+ final FocusPanel focusPanel = new FocusPanel(outer);\r
+ // Inner contains generalPanel and permPanel.\r
+ inner = new DecoratedTabPanel();\r
+ inner.setAnimationEnabled(true);\r
+ final VerticalPanel generalPanel = new VerticalPanel();\r
+ final HorizontalPanel buttons = new HorizontalPanel();\r
+ final VerticalPanel verPanel = new VerticalPanel();\r
+ final HorizontalPanel vPanel = new HorizontalPanel();\r
+\r
+ inner.add(generalPanel, "General");\r
+ inner.add(verPanel, "Versions");\r
+ inner.selectTab(0);\r
+\r
+ final FlexTable generalTable = new FlexTable();\r
+ generalTable.setText(0, 0, String.valueOf(files.size())+" files selected");\r
+ generalTable.setText(1, 0, "Folder");\r
+ generalTable.setText(2, 0, "Tags");\r
+ FileResource firstFile = files.get(0);\r
+ if(firstFile.getFolderName() != null)\r
+ generalTable.setText(1, 1, firstFile.getFolderName());\r
+ else\r
+ generalTable.setText(1, 1, "-");\r
+\r
+ // Find if tags are identical\r
+ List<String> tagsList = files.get(0).getTags();\r
+ List<String> tagss;\r
+ for (int i=1; i<files.size(); i++) {\r
+ tagss = files.get(i).getTags();\r
+ if (tagsList.size() != tagss.size() || !tagsList.containsAll(tagss)) {\r
+ tagsList = null;\r
+ break;\r
+ }\r
+ }\r
+ // Get the tags.\r
+ StringBuffer tagsBuffer = new StringBuffer();\r
+ if (tagsList==null)\r
+ tagsBuffer.append(MULTIPLE_VALUES_TEXT);\r
+ else {\r
+ Iterator i = tagsList.iterator();\r
+ while (i.hasNext()) {\r
+ String tag = (String) i.next();\r
+ tagsBuffer.append(tag).append(", ");\r
+ }\r
+ if (tagsBuffer.length() > 1)\r
+ tagsBuffer.delete(tagsBuffer.length() - 2, tagsBuffer.length() - 1);\r
+ }\r
+ initialTagText = tagsBuffer.toString();\r
+ tags.setText(initialTagText);\r
+ tags.addFocusHandler(new FocusHandler() {\r
+ @Override\r
+ public void onFocus(FocusEvent event) {\r
+ if (MULTIPLE_VALUES_TEXT.equals(tags.getText()))\r
+ tags.setText("");\r
+ }\r
+ }\r
+ );\r
+\r
+ generalTable.setWidget(2, 1, tags);\r
+ generalTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setColSpan(0, 0, 2);\r
+ generalTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(2, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(0, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(1, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(2, 1, "props-values");\r
+ generalTable.setCellSpacing(4);\r
+\r
+ // Create the 'OK' button, along with a listener that hides the dialog\r
+ // when the button is clicked.\r
+ final Button ok = new Button("OK", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ accept();\r
+ closeDialog();\r
+ }\r
+ });\r
+ buttons.add(ok);\r
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
+ // Create the 'Cancel' button, along with a listener that hides the\r
+ // dialog when the button is clicked.\r
+ final Button cancel = new Button("Cancel", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ closeDialog();\r
+ }\r
+ });\r
+ buttons.add(cancel);\r
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ buttons.setSpacing(8);\r
+ buttons.addStyleName("gss-TabPanelBottom");\r
+\r
+ generalPanel.add(generalTable);\r
+\r
+ // Asynchronously retrieve the tags defined by this user.\r
+ DeferredCommand.addCommand(new Command() {\r
+\r
+ @Override\r
+ public void execute() {\r
+ updateTags();\r
+ }\r
+ });\r
+\r
+ DisclosurePanel allTags = new DisclosurePanel("All tags");\r
+ allTagsContent = new FlowPanel();\r
+ allTags.setContent(allTagsContent);\r
+ generalPanel.add(allTags);\r
+ generalPanel.setSpacing(4);\r
+\r
+\r
+ vPanel.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ vPanel.setSpacing(8);\r
+ vPanel.addStyleName("gss-TabPanelBottom");\r
+ vPanel.add(new Label("Versioned"));\r
+\r
+ vPanel.add(versionedCheck);\r
+ verPanel.add(vPanel);\r
+ outer.add(inner);\r
+ outer.add(buttons);\r
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
+ outer.addStyleName("gss-TabPanelBottom");\r
+\r
+ focusPanel.setFocus(true);\r
+ setWidget(outer);\r
+ }\r
+\r
+\r
+ /**\r
+ * Accepts any change and updates the file\r
+ *\r
+ */\r
+ @Override\r
+ protected void accept() {\r
+ JSONObject json = new JSONObject();\r
+ if ( versionedCheck.getState()!=null && !versionedCheck.getState().equals(initialVersioned) )\r
+ json.put("versioned", JSONBoolean.getInstance(versionedCheck.getState()));\r
+\r
+ JSONArray taga = new JSONArray();\r
+ int i = 0;\r
+ String tagText = tags.getText();\r
+ if (!MULTIPLE_VALUES_TEXT.equals(tagText) && !initialTagText.equals(tagText)) {\r
+ String[] tagset = tagText.split(",");\r
+ for (String t : tagset) {\r
+ JSONString to = new JSONString(t);\r
+ taga.set(i, to);\r
+ i++;\r
+ }\r
+ json.put("tags", taga);\r
+ }\r
+ String jsonString = json.toString();\r
+ if(jsonString.equals("{}")){\r
+ GWT.log("NO CHANGES", null);\r
+ return;\r
+ }\r
+ final List<String> fileIds = new ArrayList<String>();\r
+ for(FileResource f : files)\r
+ fileIds.add(f.getUri()+"?update=");\r
+ MultiplePostCommand rt = new MultiplePostCommand(fileIds.toArray(new String[0]), jsonString, 200){\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ GSS.get().getTreeView().refreshCurrentNode(false);\r
+ }\r
+\r
+ @Override\r
+ public void onError(String p, Throwable t) {\r
+ GWT.log("", t);\r
+ if(t instanceof RestException){\r
+ int statusCode = ((RestException)t).getHttpStatusCode();\r
+ if(statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions");\r
+ else if(statusCode == 404)\r
+ GSS.get().displayError("File does not exist");\r
+ else if(statusCode == 409)\r
+ GSS.get().displayError("A file with the same name already exists");\r
+ else if(statusCode == 413)\r
+ GSS.get().displayError("Your quota has been exceeded");\r
+ else\r
+ GSS.get().displayError("Unable to modify file::"+((RestException)t).getHttpStatusText());\r
+ }\r
+ else\r
+ GSS.get().displayError("System error modifying file:"+t.getMessage());\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(rt);\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.commands.CopyCommand;
+import org.gss_project.gss.web.client.commands.CutCommand;
+import org.gss_project.gss.web.client.commands.DeleteCommand;
+import org.gss_project.gss.web.client.commands.EmptyTrashCommand;
+import org.gss_project.gss.web.client.commands.NewFolderCommand;
+import org.gss_project.gss.web.client.commands.PasteCommand;
+import org.gss_project.gss.web.client.commands.PropertiesCommand;
+import org.gss_project.gss.web.client.commands.RefreshCommand;
+import org.gss_project.gss.web.client.commands.RestoreTrashCommand;
+import org.gss_project.gss.web.client.commands.ToTrashCommand;
+import org.gss_project.gss.web.client.commands.UploadFileCommand;
+import org.gss_project.gss.web.client.rest.resource.MyFolderResource;
+import org.gss_project.gss.web.client.rest.resource.OtherUserResource;
+import org.gss_project.gss.web.client.rest.resource.OthersFolderResource;
+import org.gss_project.gss.web.client.rest.resource.OthersResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.SharedFolderResource;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashFolderResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * The 'Folder Context' menu implementation.
+ */
+public class FolderContextMenu extends PopupPanel {
+
+ /**
+ * The widget's images.
+ */
+ private final Images images;
+
+ /**
+ * The image bundle for this widget's images that reuses images defined in
+ * other menus.
+ */
+ public interface Images extends ClientBundle,FileMenu.Images, EditMenu.Images {
+ }
+
+ private MenuItem pasteItem;
+
+ /**
+ * The widget's constructor.
+ *
+ * @param newImages the image bundle passed on by the parent object
+ */
+ public FolderContextMenu(final Images newImages) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(true);
+ setAnimationEnabled(true);
+ images = newImages;
+
+ pasteItem = new MenuItem("<span id = 'folderContextMenu.paste'>" + AbstractImagePrototype.create(newImages.paste()).getHTML() + " Paste</span>", true, new PasteCommand(this));
+ MenuBar contextMenu = new MenuBar(true);
+
+ RestResource selectedItem = GSS.get().getTreeView().getSelection();
+
+ if(selectedItem != null)
+ if(selectedItem instanceof MyFolderResource){
+ MenuItem newFolder = new MenuItem("<span id = 'folderContextMenu.newFolder'>" + AbstractImagePrototype.create(newImages.folderNew()).getHTML() + " New Folder</span>", true, new NewFolderCommand(this, images));
+ contextMenu.addItem(newFolder);
+
+ MenuItem upload = new MenuItem("<span id = 'folderContextMenu.upload'>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ contextMenu.addItem(upload);
+
+ boolean notRootFolder =(((MyFolderResource) selectedItem).getResource()).getParentURI() != null ? true : false;
+ if (notRootFolder) {
+ // do not show the copy & cut option for the user's root folder
+ MenuItem cut = new MenuItem("<span id = 'folderContextMenu.cut'>" + AbstractImagePrototype.create(newImages.cut()).getHTML() + " Cut</span>", true, new CutCommand(this));
+ contextMenu.addItem(cut);
+
+ }
+ MenuItem copy = new MenuItem("<span id = 'folderContextMenu.copy'>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy</span>", true, new CopyCommand(this));
+ contextMenu.addItem(copy);
+ contextMenu.addItem(pasteItem);
+ if (notRootFolder) {
+ // do not show delete options for the user's root folder
+ MenuItem moveToTrash = new MenuItem("<span id = 'folderContextMenu.moveToTrash'>" + AbstractImagePrototype.create(newImages.emptyTrash()).getHTML() + " Move to Trash</span>", true, new ToTrashCommand(this));
+ contextMenu.addItem(moveToTrash);
+
+ MenuItem delete = new MenuItem("<span id = 'folderContextMenu.delete'>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, newImages));
+ contextMenu.addItem(delete);
+ }
+
+ MenuItem refresh = new MenuItem("<span id = 'folderContextMenu.refresh'>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ contextMenu.addItem(refresh);
+
+ MenuItem sharing = new MenuItem("<span id = 'folderContextMenu.sharing'>" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Sharing</span>", true, new PropertiesCommand(this, newImages, 1));
+ contextMenu.addItem(sharing);
+
+ MenuItem properties = new MenuItem("<span id = 'folderContextMenu.properties'>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties</span>", true, new PropertiesCommand(this, newImages, 0));
+ contextMenu.addItem(properties);
+ }
+
+ if(selectedItem instanceof SharedFolderResource){
+ MenuItem newFolder = new MenuItem("<span id = 'folderContextMenu.newFolder'>" + AbstractImagePrototype.create(newImages.folderNew()).getHTML() + " New Folder</span>", true, new NewFolderCommand(this, images));
+ contextMenu.addItem(newFolder);
+
+ MenuItem upload = new MenuItem("<span id = 'folderContextMenu.upload'>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ contextMenu.addItem(upload);
+
+ MenuItem cut = new MenuItem("<span id = 'folderContextMenu.cut'>" + AbstractImagePrototype.create(newImages.cut()).getHTML() + " Cut</span>", true, new CutCommand(this));
+ contextMenu.addItem(cut);
+
+ MenuItem copy = new MenuItem("<span id = 'folderContextMenu.copy'>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy</span>", true, new CopyCommand(this));
+ contextMenu.addItem(copy);
+
+ contextMenu.addItem(pasteItem);
+
+ MenuItem moveToTrash = new MenuItem("<span id = 'folderContextMenu.moveToTrash'>" + AbstractImagePrototype.create(newImages.emptyTrash()).getHTML() + " Move to Trash</span>", true, new ToTrashCommand(this));
+ contextMenu.addItem(moveToTrash);
+
+ MenuItem delete = new MenuItem("<span id = 'folderContextMenu.delete'>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, newImages));
+ contextMenu.addItem(delete);
+
+ MenuItem refresh = new MenuItem("<span id = 'folderContextMenu.refresh'>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ contextMenu.addItem(refresh);
+
+ MenuItem sharing = new MenuItem("<span id = 'folderContextMenu.sharing'>" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Sharing</span>", true, new PropertiesCommand(this, newImages, 1));
+ contextMenu.addItem(sharing);
+
+ MenuItem properties = new MenuItem("<span id = 'folderContextMenu.properties'>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties</span>", true, new PropertiesCommand(this, newImages, 0));
+ contextMenu.addItem(properties);
+
+ }
+ if(selectedItem instanceof TrashFolderResource){
+ MenuItem restore = new MenuItem("<span id = 'folderContextMenu.restore'>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Restore folder and contents</span>", true, new RestoreTrashCommand(this));
+ contextMenu.addItem(restore);
+
+ MenuItem delete = new MenuItem("<span id = 'folderContextMenu.delete'>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, newImages));
+ contextMenu.addItem(delete);
+
+ MenuItem refresh = new MenuItem("<span id = 'folderContextMenu.refresh'>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ contextMenu.addItem(refresh);
+
+ }
+ if(selectedItem instanceof OthersFolderResource){
+ MenuItem newFolder = new MenuItem("<span id = 'folderContextMenu.newFolder'>" + AbstractImagePrototype.create(newImages.folderNew()).getHTML() + " New Folder</span>", true, new NewFolderCommand(this, images));
+ contextMenu.addItem(newFolder);
+
+ MenuItem upload = new MenuItem("<span id ='folderContextMenu.upload'>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ contextMenu.addItem(upload);
+
+ MenuItem cut = new MenuItem("<span id = 'folderContextMenu.cut'>" + AbstractImagePrototype.create(newImages.cut()).getHTML() + " Cut</span>", true, new CutCommand(this));
+ contextMenu.addItem(cut);
+
+ MenuItem copy = new MenuItem("<span id = 'folderContextMenu.copy'>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy</span>", true, new CopyCommand(this));
+ contextMenu.addItem(copy);
+
+ contextMenu.addItem(pasteItem);
+
+ MenuItem moveToTrash = new MenuItem("<span id = 'folderContextMenu.moveToTrash'>" + AbstractImagePrototype.create(newImages.emptyTrash()).getHTML() + " Move to Trash</span>", true, new ToTrashCommand(this));
+ contextMenu.addItem(moveToTrash);
+
+ MenuItem delete = new MenuItem("<span id = 'folderContextMenu.delete'>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, newImages));
+ contextMenu.addItem(delete);
+
+ MenuItem refresh = new MenuItem("<span id = 'folderContextMenu.delete'>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ contextMenu.addItem(refresh);
+
+ MenuItem sharing = new MenuItem("<span id = 'folderContextMenu.sharing'>" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Sharing</span>", true, new PropertiesCommand(this, newImages, 1));
+ contextMenu.addItem(sharing);
+
+ MenuItem properties = new MenuItem("<span id = 'folderContextMenu.properties'>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties</span>", true, new PropertiesCommand(this, newImages, 0));
+ contextMenu.addItem(properties);
+
+ }
+ if(selectedItem instanceof TrashResource){
+ MenuItem restore = new MenuItem("<span id ='folderContextMenu.restore'>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Restore Trash</span>", true, new RestoreTrashCommand(this));
+ contextMenu.addItem(restore);
+
+ MenuItem emptyTrash = new MenuItem("<span id = 'folderContextMenu.emptyTrash'>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Empty Trash</span>", true, new EmptyTrashCommand(this));
+ contextMenu.addItem(emptyTrash);
+
+ MenuItem refresh = new MenuItem("<span id = 'folderContextMenu.refresh'>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ contextMenu.addItem(refresh);
+
+ }
+ if(selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource){
+ MenuItem refresh = new MenuItem("<span id = 'folderContextMenu.refresh'>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ contextMenu.addItem(refresh);
+
+ }
+
+ /*
+ if(folders.isTrashItem(selectedItem)){
+ if (folders.isTrash(selectedItem)){
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Empty Trash</span>", true, new EmptyTrashCommand(this));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ }
+ else {
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Restore folder and contents</span>", true, new RestoreTrashCommand(this));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, newImages));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ }
+ }
+ else if(folders.isFileItem(selectedItem)){
+
+ }
+ else if(!folders.isMyShares(selectedItem) && folders.isMySharedItem(selectedItem)){
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.folderNew()).getHTML() + " New Folder</span>", true, new NewFolderCommand(this, images));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.cut()).getHTML() + " Cut</span>", true, new CutCommand(this));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy</span>", true, new CopyCommand(this));
+ contextMenu.addItem(pasteItem);
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.emptyTrash()).getHTML() + " Move to Trash</span>", true, new ToTrashCommand(this));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, newImages));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Sharing</span>", true, new PropertiesCommand(this, newImages, 1));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties</span>", true, new PropertiesCommand(this, newImages, 0));
+ }
+ else if(!folders.isOthersShared(selectedItem) && folders.isOthersSharedItem(selectedItem) && !(GSS.get().getCurrentSelection() instanceof OtherUserResource)){
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.folderNew()).getHTML() + " New Folder</span>", true, new NewFolderCommand(this, images));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.fileUpdate()).getHTML() + " Upload</span>", true, new UploadFileCommand(this));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.cut()).getHTML() + " Cut</span>", true, new CutCommand(this));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy</span>", true, new CopyCommand(this));
+ contextMenu.addItem(pasteItem);
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.emptyTrash()).getHTML() + " Move to Trash</span>", true, new ToTrashCommand(this));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteCommand(this, newImages));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Sharing</span>", true, new PropertiesCommand(this, newImages, 1));
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties</span>", true, new PropertiesCommand(this, newImages, 0));
+ } else if(!selectedItem.equals(folders.getSharesItem()))
+ contextMenu.addItem("<span>" + AbstractImagePrototype.create(images.refresh()).getHTML() + " Refresh</span>", true, new RefreshCommand(this, images));
+ */
+
+ add(contextMenu);
+ if (GSS.get().getClipboard().hasFolderOrFileItem())
+ pasteItem.setVisible(true);
+ else
+ pasteItem.setVisible(false);
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.FilePropertiesDialog.Images;\r
+import org.gss_project.gss.web.client.rest.PostCommand;\r
+import org.gss_project.gss.web.client.rest.RestException;\r
+import org.gss_project.gss.web.client.rest.resource.FolderResource;\r
+import org.gss_project.gss.web.client.rest.resource.GroupResource;\r
+import org.gss_project.gss.web.client.rest.resource.PermissionHolder;\r
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;\r
+\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.ChangeEvent;\r
+import com.google.gwt.event.dom.client.ChangeHandler;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.http.client.URL;\r
+import com.google.gwt.i18n.client.DateTimeFormat;\r
+import com.google.gwt.json.client.JSONArray;\r
+import com.google.gwt.json.client.JSONBoolean;\r
+import com.google.gwt.json.client.JSONObject;\r
+import com.google.gwt.json.client.JSONString;\r
+import com.google.gwt.user.client.DeferredCommand;\r
+import com.google.gwt.user.client.Event.NativePreviewEvent;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.CheckBox;\r
+import com.google.gwt.user.client.ui.DecoratedTabPanel;\r
+import com.google.gwt.user.client.ui.DialogBox;\r
+import com.google.gwt.user.client.ui.FlexTable;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.Label;\r
+import com.google.gwt.user.client.ui.TabPanel;\r
+import com.google.gwt.user.client.ui.TextBox;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'Folder properties' dialog box implementation.\r
+ */\r
+public class FolderPropertiesDialog extends DialogBox {\r
+\r
+ private List<GroupResource> groups = null;\r
+\r
+ final PermissionsList permList;\r
+\r
+ private CheckBox readForAll;\r
+\r
+ /**\r
+ * The widget that holds the folderName of the folder.\r
+ */\r
+ private TextBox folderName = new TextBox();\r
+\r
+ /**\r
+ * A flag that denotes whether the dialog will be used to create or modify a\r
+ * folder.\r
+ */\r
+ private final boolean create;\r
+\r
+ final FolderResource folder;\r
+\r
+ final TabPanel inner;\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ *\r
+ * @param images the image icons from the file properties dialog\r
+ * @param _create true if the dialog is displayed for creating a new\r
+ * sub-folder of the selected folder, false if it is displayed\r
+ * for modifying the selected folder\r
+ */\r
+ public FolderPropertiesDialog(Images images, boolean _create, final List<GroupResource> _groups) {\r
+ setAnimationEnabled(true);\r
+\r
+ // Enable IE selection for the dialog (must disable it upon closing it)\r
+ GSS.enableIESelection();\r
+\r
+ create = _create;\r
+ \r
+ folder = ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource();\r
+ permList = new PermissionsList(images, folder.getPermissions(), folder.getOwner());\r
+ groups = _groups;\r
+\r
+ // Use this opportunity to set the dialog's caption.\r
+ if (create)\r
+ setText("Create folder");\r
+ else\r
+ setText("Folder properties");\r
+\r
+ // Outer contains inner and buttons\r
+ VerticalPanel outer = new VerticalPanel();\r
+ // Inner contains generalPanel and permPanel\r
+ inner = new DecoratedTabPanel();\r
+ inner.setAnimationEnabled(true);\r
+ VerticalPanel generalPanel = new VerticalPanel();\r
+ VerticalPanel permPanel = new VerticalPanel();\r
+ final HorizontalPanel permForAll = new HorizontalPanel();\r
+ final HorizontalPanel pathPanel = new HorizontalPanel();\r
+ HorizontalPanel buttons = new HorizontalPanel();\r
+ HorizontalPanel permButtons = new HorizontalPanel();\r
+\r
+ inner.add(generalPanel, "General");\r
+ if (!create)\r
+ inner.add(permPanel, "Sharing");\r
+ inner.selectTab(0);\r
+\r
+ final Label folderNameNote = new Label("Please note that slashes ('/') are not allowed in folder names.", true);\r
+ folderNameNote.setVisible(false);\r
+ folderNameNote.setStylePrimaryName("gss-readForAllNote");\r
+\r
+ FlexTable generalTable = new FlexTable();\r
+ generalTable.setText(0, 0, "Name");\r
+ generalTable.setText(1, 0, "Parent");\r
+ generalTable.setText(2, 0, "Creator");\r
+ generalTable.setText(3, 0, "Last modified");\r
+ folderName.setText(create ? "" : folder.getName());\r
+ folderName.getElement().setId("folderPropertiesDialog.textBox.name");\r
+ generalTable.setWidget(0, 1, folderName);\r
+ folderName.addChangeHandler(new ChangeHandler() {\r
+ \r
+ @Override\r
+ public void onChange(ChangeEvent event) {\r
+ if(folderName.getText().contains("/"))\r
+ folderNameNote.setVisible(true);\r
+ else\r
+ folderNameNote.setVisible(false); \r
+ \r
+ }\r
+ });\r
+\r
+\r
+ if (create)\r
+ generalTable.setText(1, 1, folder.getName());\r
+ else if(folder.getParentName() == null)\r
+ generalTable.setText(1, 1, "-");\r
+ else\r
+ generalTable.setText(1, 1, folder.getParentName());\r
+ generalTable.setWidget(0, 2, folderNameNote);\r
+ generalTable.setText(2, 1, folder.getOwner());\r
+ DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");\r
+ if(folder.getModificationDate() != null)\r
+ generalTable.setText(3, 1, formatter.format(folder.getModificationDate()));\r
+ generalTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(2, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(3, 0, "props-labels");\r
+ generalTable.getFlexCellFormatter().setStyleName(0, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(1, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(2, 1, "props-values");\r
+ generalTable.getFlexCellFormatter().setStyleName(3, 1, "props-values");\r
+ generalTable.setCellSpacing(4);\r
+\r
+ // Create the 'Create/Update' button, along with a listener that hides the dialog\r
+ // when the button is clicked and quits the application.\r
+ String okLabel;\r
+ if (create)\r
+ okLabel = "Create";\r
+ else\r
+ okLabel = "Update";\r
+ Button ok = new Button(okLabel, new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) { \r
+ if(folderName.getText().contains("/"))\r
+ folderNameNote.setVisible(true);\r
+ else {\r
+ folderNameNote.setVisible(false);\r
+ createOrUpdateFolder();\r
+ closeDialog();\r
+ }\r
+\r
+ }\r
+ });\r
+ ok.getElement().setId("folderPropertiesDialog.button.ok");\r
+ buttons.add(ok);\r
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
+ // Create the 'Cancel' button, along with a listener that hides the\r
+ // dialog\r
+ // when the button is clicked.\r
+ Button cancel = new Button("Cancel", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ closeDialog();\r
+ }\r
+ });\r
+ cancel.getElement().setId("folderPropertiesDialog.button.cancel");\r
+ buttons.add(cancel);\r
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ buttons.setSpacing(8);\r
+ buttons.addStyleName("gss-TabPanelBottom");\r
+\r
+ Button add = new Button("Add Group", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, false);\r
+ dlg.center();\r
+ }\r
+ });\r
+ add.getElement().setId("folderPropertiesDialog.button.addGroup");\r
+ permButtons.add(add);\r
+ permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);\r
+\r
+ Button addUser = new Button("Add User", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, true);\r
+ dlg.center();\r
+ }\r
+ });\r
+ addUser.getElement().setId("folderPropertiesDialog.button.addUser");\r
+ permButtons.add(addUser);\r
+ permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);\r
+\r
+ permButtons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ permButtons.setSpacing(8);\r
+ permButtons.addStyleName("gss-TabPanelBottom");\r
+\r
+ final Label readForAllNote = new Label("When this option is enabled, the folder will be readable" +\r
+ " by everyone. By checking this option, you are certifying that you have the right to " +\r
+ "distribute this folder's contents and that it does not violate the Terms of Use.", true);\r
+ readForAllNote.setVisible(false);\r
+ readForAllNote.setStylePrimaryName("gss-readForAllNote");\r
+\r
+ readForAll = new CheckBox();\r
+ readForAll.getElement().setId("folderPropertiesDialog.checkBox.public");\r
+ readForAll.setValue(folder.isReadForAll());\r
+ readForAll.addClickHandler(new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ readForAllNote.setVisible(readForAll.getValue());\r
+ }\r
+\r
+ });\r
+\r
+ generalPanel.add(generalTable);\r
+ permPanel.add(permList);\r
+ permPanel.add(permButtons);\r
+\r
+ // Only show the read for all permission if the user is the owner.\r
+ if (folder.getOwner().equals(GSS.get().getCurrentUserResource().getUsername())) {\r
+ permForAll.add(new Label("Public"));\r
+ permForAll.add(readForAll);\r
+ permForAll.setSpacing(8);\r
+ permForAll.addStyleName("gss-TabPanelBottom");\r
+ permForAll.add(readForAllNote);\r
+ permPanel.add(permForAll);\r
+ }\r
+ TextBox path = new TextBox();\r
+ path.getElement().setId("folderPropertiesDialog.textBox.link");\r
+ path.setWidth("100%");\r
+ path.addClickHandler(new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ GSS.enableIESelection();\r
+ ((TextBox) event.getSource()).selectAll();\r
+ GSS.preventIESelection();\r
+ }\r
+\r
+ });\r
+ path.setText(folder.getUri());\r
+ path.setTitle("Use this link for sharing the folder via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
+ path.setWidth("100%");\r
+ path.setReadOnly(true);\r
+ pathPanel.setWidth("100%");\r
+ pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
+ pathPanel.add(new Label("Link"));\r
+ pathPanel.setSpacing(8);\r
+ pathPanel.addStyleName("gss-TabPanelBottom");\r
+ pathPanel.add(path);\r
+ permPanel.add(pathPanel);\r
+\r
+ outer.add(inner);\r
+ outer.add(buttons);\r
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
+ outer.addStyleName("gss-TabPanelBottom");\r
+\r
+ setWidget(outer);\r
+\r
+ /*if (create)\r
+ folderName.setFocus(true);\r
+ else\r
+ ok.setFocus(true);*/\r
+ }\r
+\r
+ @Override\r
+ public void center() {\r
+ super.center();\r
+ folderName.setFocus(true);\r
+ }\r
+\r
+ @Override\r
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
+ super.onPreviewNativeEvent(preview);\r
+\r
+ NativeEvent evt = preview.getNativeEvent();\r
+ if (evt.getType().equals("keydown"))\r
+ // Use the popup's key preview hooks to close the dialog when either\r
+ // enter or escape is pressed.\r
+ switch (evt.getKeyCode()) {\r
+ case KeyCodes.KEY_ENTER:\r
+ closeDialog();\r
+ createOrUpdateFolder();\r
+ break;\r
+ case KeyCodes.KEY_ESCAPE:\r
+ closeDialog();\r
+ break;\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Enables IE selection prevention and hides the dialog\r
+ * (we disable the prevention on creation of the dialog)\r
+ */\r
+ public void closeDialog() {\r
+ GSS.preventIESelection();\r
+ hide();\r
+ }\r
+\r
+ /**\r
+ * Generate an RPC request to create a new folder.\r
+ *\r
+ * @param userId the ID of the user whose namespace will be searched for\r
+ * folders\r
+ * @param _folderName the name of the folder to create\r
+ */\r
+ private void createFolder() {\r
+ String name = folderName.getText();\r
+ if (!GSS.isValidResourceName(name)) {\r
+ GSS.get().displayError("The folder name '" + name + "' is invalid");\r
+ return;\r
+ }\r
+ PostCommand ep = new PostCommand(folder.getUri() + "?new=" +\r
+ URL.encodeComponent(name), "", 201) {\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ //TODO:CELLTREE\r
+ if(folder.getUri().equals(GSS.get().getTreeView().getMyFolders().getUri())){\r
+ GSS.get().getTreeView().updateRootNode();\r
+ }\r
+ else\r
+ GSS.get().getTreeView().updateNodeChildren((RestResourceWrapper) GSS.get().getTreeView().getSelection());\r
+ //GSS.get().getFolders().updateFolder((DnDTreeItem) GSS.get().getFolders().getCurrent());\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ if(t instanceof RestException){\r
+ int statusCode = ((RestException)t).getHttpStatusCode();\r
+ if(statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary" +\r
+ " permissions or a folder with same name " +\r
+ "already exists");\r
+ else if(statusCode == 404)\r
+ GSS.get().displayError("Resource not found");\r
+ else\r
+ GSS.get().displayError("Unable to create folder:" +\r
+ ((RestException)t).getHttpStatusText());\r
+ }\r
+ else\r
+ GSS.get().displayError("System error creating folder:" +\r
+ t.getMessage());\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(ep);\r
+\r
+ }\r
+\r
+ /**\r
+ * Upon closing the dialog by clicking OK or pressing ENTER this method does\r
+ * the actual work of modifying folder properties or creating a new Folder\r
+ * depending on the value of the create field\r
+ *\r
+ * @param userId\r
+ */\r
+ private void createOrUpdateFolder() {\r
+ if (create)\r
+ createFolder();\r
+ else\r
+ updateFolder();\r
+\r
+ }\r
+\r
+ private void updateFolder() {\r
+ permList.updatePermissionsAccordingToInput();\r
+ Set<PermissionHolder> perms = permList.getPermissions();\r
+ JSONObject json = new JSONObject();\r
+ if(!folder.getName().equals(folderName.getText()))\r
+ json.put("name", new JSONString(folderName.getText()));\r
+ //only update the read for all perm if the user is the owner\r
+ if (readForAll.getValue() != folder.isReadForAll())\r
+ if (folder.getOwner().equals(GSS.get().getCurrentUserResource().getUsername()))\r
+ json.put("readForAll", JSONBoolean.getInstance(readForAll.getValue()));\r
+ if (permList.hasChanges()) {\r
+ JSONArray perma = new JSONArray();\r
+ int i=0;\r
+ for(PermissionHolder p : perms){\r
+ JSONObject po = new JSONObject();\r
+ if(p.getUser() != null)\r
+ po.put("user", new JSONString(p.getUser()));\r
+ if(p.getGroup() != null)\r
+ po.put("group", new JSONString(p.getGroup()));\r
+ po.put("read", JSONBoolean.getInstance(p.isRead()));\r
+ po.put("write", JSONBoolean.getInstance(p.isWrite()));\r
+ po.put("modifyACL", JSONBoolean.getInstance(p.isModifyACL()));\r
+ perma.set(i,po);\r
+ i++;\r
+ }\r
+ json.put("permissions", perma);\r
+ GWT.log(json.toString(), null);\r
+ }\r
+ PostCommand ep = new PostCommand(folder.getUri()+"?update=", json.toString(), 200){\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ //TODO:CELLTREE\r
+ \r
+ if(getPostBody() != null && !"".equals(getPostBody().trim())){\r
+ \r
+ \r
+ FolderResource fres = ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource();\r
+ String initialPath = fres.getUri();\r
+ String newPath = getPostBody().trim();\r
+ fres.setUri(newPath);\r
+ ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource().setUri(newPath);\r
+ ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).setUri(newPath);\r
+ GSS.get().getTreeView().updateNodeChildren(fres.getParentURI());\r
+ if (permList.hasChanges()) {\r
+ GSS.get().getTreeView().updateMySharedNode();\r
+ }\r
+ /*\r
+ if(folderItem.getParentItem() != null && ((DnDTreeItem)folderItem.getParentItem()).getFolderResource() != null){\r
+ ((DnDTreeItem)folderItem.getParentItem()).getFolderResource().removeSubfolderPath(initialPath);\r
+ ((DnDTreeItem)folderItem.getParentItem()).getFolderResource().getSubfolderPaths().add(newPath);\r
+ }*/\r
+ }\r
+ //GSS.get().getFolders().updateFolder( (DnDTreeItem) GSS.get().getFolders().getCurrent());\r
+ \r
+ GSS.get().showFileList(true);\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ if(t instanceof RestException){\r
+ int statusCode = ((RestException)t).getHttpStatusCode();\r
+ if(statusCode == 405)\r
+ GSS.get().displayError("You don't have the necessary permissions or" +\r
+ " a folder with same name already exists");\r
+ else if(statusCode == 404)\r
+ GSS.get().displayError("Resource not found, or user specified in sharing does not exist");\r
+ else\r
+ GSS.get().displayError("Unable to update folder: "+((RestException)t).getHttpStatusText());\r
+ }\r
+ else\r
+ GSS.get().displayError("System error moifying file: "+t.getMessage());\r
+ //TODO:CELLTREE\r
+ //GSS.get().getFolders().updateFolder( (DnDTreeItem) GSS.get().getFolders().getCurrent());\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(ep);\r
+ }\r
+\r
+ public void selectTab(int _tab) {\r
+ inner.selectTab(_tab);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.clipboard.Clipboard;
+import org.gss_project.gss.web.client.commands.GetUserCommand;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.OtherUserResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
+import com.google.gwt.event.logical.shared.SelectionEvent;
+import com.google.gwt.event.logical.shared.SelectionHandler;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.Cookies;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.History;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.DecoratedTabPanel;
+import com.google.gwt.user.client.ui.DockPanel;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.user.client.ui.HorizontalSplitPanel;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.TabPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+/**
+ * Entry point classes define <code>onModuleLoad()</code>.
+ */
+public class GSS implements EntryPoint, ResizeHandler {
+
+ /**
+ * A constant that denotes the completion of an IncrementalCommand.
+ */
+ public static final boolean DONE = false;
+
+ public static final int VISIBLE_FILE_COUNT = 25;
+
+ /**
+ * Instantiate an application-level image bundle. This object will provide
+ * programmatic access to all the images needed by widgets.
+ */
+ private static Images images = (Images) GWT.create(Images.class);
+
+ private GlassPanel glassPanel = new GlassPanel();
+
+ /**
+ * An aggregate image bundle that pulls together all the images for this
+ * application into a single bundle.
+ */
+ public interface Images extends ClientBundle, TopPanel.Images, StatusPanel.Images, FileMenu.Images, EditMenu.Images, SettingsMenu.Images, GroupMenu.Images, FilePropertiesDialog.Images, MessagePanel.Images, FileList.Images, SearchResults.Images, Search.Images, Groups.Images, CellTreeView.Images {
+
+ @Source("org/gss_project/gss/resources/document.png")
+ ImageResource folders();
+
+ @Source("org/gss_project/gss/resources/edit_group_22.png")
+ ImageResource groups();
+
+ @Source("org/gss_project/gss/resources/search.png")
+ ImageResource search();
+ }
+
+ /**
+ * The single GSS instance.
+ */
+ private static GSS singleton;
+
+ /**
+ * Gets the singleton GSS instance.
+ *
+ * @return the GSS object
+ */
+ public static GSS get() {
+ if (GSS.singleton == null)
+ GSS.singleton = new GSS();
+ return GSS.singleton;
+ }
+
+ /**
+ * The Application Clipboard implementation;
+ */
+ private Clipboard clipboard = new Clipboard();
+
+ private UserResource currentUserResource;
+
+ /**
+ * The top panel that contains the menu bar.
+ */
+ private TopPanel topPanel;
+
+ /**
+ * The panel that contains the various system messages.
+ */
+ private MessagePanel messagePanel = new MessagePanel(GSS.images);
+
+ /**
+ * The bottom panel that contains the status bar.
+ */
+ private StatusPanel statusPanel = new StatusPanel(GSS.images);
+
+ /**
+ * The top right panel that displays the logged in user details
+ */
+ private UserDetailsPanel userDetailsPanel = new UserDetailsPanel();
+
+ /**
+ * The file list widget.
+ */
+ private FileList fileList;
+
+ /**
+ * The group list widget.
+ */
+ private Groups groups = new Groups(images);
+
+ /**
+ * The search result widget.
+ */
+ private SearchResults searchResults;
+
+ /**
+ * The tab panel that occupies the right side of the screen.
+ */
+ private TabPanel inner = new DecoratedTabPanel(){
+
+ public void onBrowserEvent(com.google.gwt.user.client.Event event) {
+ if (DOM.eventGetType(event) == Event.ONCONTEXTMENU){
+ if(isFileListShowing()){
+ getFileList().showContextMenu(event);
+ }
+ else if(isUserListVisible()){
+ getGroups().setCurrent(null);
+ getGroups().showPopup(event.getClientX(),event.getClientY());
+ }
+ }
+ };
+ };
+
+ /**
+ * The split panel that will contain the left and right panels.
+ */
+ private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
+
+ /**
+ * The horizontal panel that will contain the search and status panels.
+ */
+ private DockPanel searchStatus = new DockPanel();
+
+ /**
+ * The search widget.
+ */
+ private Search search;
+
+ /**
+ * The widget that displays the tree of folders.
+ */
+
+ private CellTreeView treeView = new CellTreeView(images);
+ /**
+ * The currently selected item in the application, for use by the Edit menu
+ * commands. Potential types are Folder, File, User and Group.
+ */
+ private Object currentSelection;
+
+ /**
+ * The authentication token of the current user.
+ */
+ private String token;
+
+ /**
+ * The WebDAV password of the current user
+ */
+ private String webDAVPassword;
+
+
+
+ public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
+
+ @Override
+ public void onModuleLoad() {
+ // Initialize the singleton before calling the constructors of the
+ // various widgets that might call GSS.get().
+ singleton = this;
+ RootPanel.get().add(glassPanel, 0, 0);
+ parseUserCredentials();
+
+ topPanel = new TopPanel(GSS.images);
+ topPanel.setWidth("100%");
+
+ messagePanel.setWidth("100%");
+ messagePanel.setVisible(false);
+
+ search = new Search(images);
+ searchStatus.add(search, DockPanel.WEST);
+ searchStatus.add(userDetailsPanel, DockPanel.EAST);
+ searchStatus.setCellHorizontalAlignment(userDetailsPanel, HasHorizontalAlignment.ALIGN_RIGHT);
+ searchStatus.setCellVerticalAlignment(search, HasVerticalAlignment.ALIGN_MIDDLE);
+ searchStatus.setCellVerticalAlignment(userDetailsPanel, HasVerticalAlignment.ALIGN_MIDDLE);
+ searchStatus.setWidth("100%");
+
+ fileList = new FileList(images);
+
+ searchResults = new SearchResults(images);
+
+ // Inner contains the various lists.
+ inner.sinkEvents(Event.ONCONTEXTMENU);
+ inner.setAnimationEnabled(true);
+ inner.getTabBar().addStyleName("gss-MainTabBar");
+ inner.getDeckPanel().addStyleName("gss-MainTabPanelBottom");
+ inner.add(fileList, createHeaderHTML(AbstractImagePrototype.create(images.folders()), "Files"), true);
+
+ inner.add(groups, createHeaderHTML(AbstractImagePrototype.create(images.groups()), "Groups"), true);
+ inner.add(searchResults, createHeaderHTML(AbstractImagePrototype.create(images.search()), "Search Results"), true);
+ //inner.add(new CellTreeView(images), createHeaderHTML(AbstractImagePrototype.create(images.search()), "Cell tree sample"), true);
+ inner.setWidth("100%");
+ inner.selectTab(0);
+
+ inner.addSelectionHandler(new SelectionHandler<Integer>() {
+
+ @Override
+ public void onSelection(SelectionEvent<Integer> event) {
+ int tabIndex = event.getSelectedItem();
+// TreeItem treeItem = GSS.get().getFolders().getCurrent();
+ switch (tabIndex) {
+ case 0:
+// Files tab selected
+ //fileList.clearSelectedRows();
+ fileList.updateCurrentlyShowingStats();
+ break;
+ case 1:
+// Groups tab selected
+ groups.updateCurrentlyShowingStats();
+ updateHistory("Groups");
+ break;
+ case 2:
+// Search tab selected
+ searchResults.clearSelectedRows();
+ searchResults.updateCurrentlyShowingStats();
+ updateHistory("Search");
+ break;
+ }
+ }
+ });
+// If the application starts with no history token, redirect to a new "Files" state
+ String initToken = History.getToken();
+ if(initToken.length() == 0)
+ History.newItem("Files");
+// Add history listener to handle any history events
+ History.addValueChangeHandler(new ValueChangeHandler<String>() {
+ @Override
+ public void onValueChange(ValueChangeEvent<String> event) {
+ String tokenInput = event.getValue();
+ String historyToken = handleSpecialFolderNames(tokenInput);
+ try {
+ if(historyToken.equals("Search"))
+ inner.selectTab(2);
+ else if(historyToken.equals("Groups"))
+ inner.selectTab(1);
+ else if(historyToken.equals("Files")|| historyToken.length()==0)
+ inner.selectTab(0);
+ else {
+ /*TODO: CELLTREE
+ PopupTree popupTree = GSS.get().getFolders().getPopupTree();
+ TreeItem treeObj = GSS.get().getFolders().getPopupTree().getTreeItem(historyToken);
+ SelectionEvent.fire(popupTree, treeObj);
+ */
+ }
+ } catch (IndexOutOfBoundsException e) {
+ inner.selectTab(0);
+ }
+ }
+ });
+
+ // Add the left and right panels to the split panel.
+ splitPanel.setLeftWidget(treeView);
+ splitPanel.setRightWidget(inner);
+ splitPanel.setSplitPosition("25%");
+ splitPanel.setSize("100%", "100%");
+ splitPanel.addStyleName("gss-splitPanel");
+
+ // Create a dock panel that will contain the menu bar at the top,
+ // the shortcuts to the left, the status bar at the bottom and the
+ // right panel taking the rest.
+ VerticalPanel outer = new VerticalPanel();
+ outer.add(topPanel);
+ outer.add(searchStatus);
+ outer.add(messagePanel);
+ outer.add(splitPanel);
+ outer.add(statusPanel);
+ outer.setWidth("100%");
+ outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER);
+
+ outer.setSpacing(4);
+
+ // Hook the window resize event, so that we can adjust the UI.
+ Window.addResizeHandler(this);
+ // Clear out the window's built-in margin, because we want to take
+ // advantage of the entire client area.
+ Window.setMargin("0px");
+ // Finally, add the outer panel to the RootPanel, so that it will be
+ // displayed.
+ RootPanel.get().add(outer);
+ // Call the window resized handler to get the initial sizes setup. Doing
+ // this in a deferred command causes it to occur after all widgets'
+ // sizes have been computed by the browser.
+ DeferredCommand.addCommand(new Command() {
+
+ @Override
+ public void execute() {
+ onWindowResized(Window.getClientHeight());
+ }
+ });
+ }
+
+ /**
+ * Fetches the User object for the specified username.
+ *
+ * @param username the username of the user
+ */
+ private void fetchUser(final String username) {
+ String path = getApiPath() + username + "/";
+ GetCommand<UserResource> getUserCommand = new GetCommand<UserResource>(UserResource.class, username, path, null) {
+
+ @Override
+ public void onComplete() {
+
+ currentUserResource = getResult();
+ final String announcement = currentUserResource.getAnnouncement();
+ if (announcement != null)
+ DeferredCommand.addCommand(new Command() {
+
+ @Override
+ public void execute() {
+ displayInformation(announcement);
+ }
+ });
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("Fetching user error", t);
+ if (t instanceof RestException)
+ GSS.get().displayError("No user found:" + ((RestException) t).getHttpStatusText());
+ else
+ GSS.get().displayError("System error fetching user data:" + t.getMessage());
+ authenticateUser();
+ }
+ };
+ DeferredCommand.addCommand(getUserCommand);
+ }
+
+ /**
+ * Parse and store the user credentials to the appropriate fields.
+ */
+ private void parseUserCredentials() {
+ Configuration conf = (Configuration) GWT.create(Configuration.class);
+ String cookie = conf.authCookie();
+ String auth = Cookies.getCookie(cookie);
+ if (auth == null) {
+ authenticateUser();
+ // Redundant, but silences warnings about possible auth NPE, below.
+ return;
+ }
+ int sepIndex = auth.indexOf(conf.cookieSeparator());
+ if (sepIndex == -1)
+ authenticateUser();
+ token = auth.substring(sepIndex + 1);
+ final String username = auth.substring(0, sepIndex);
+ if (username == null)
+ authenticateUser();
+
+ refreshWebDAVPassword();
+
+ DeferredCommand.addCommand(new Command() {
+
+ @Override
+ public void execute() {
+ fetchUser(username);
+ }
+ });
+ }
+
+ /**
+ * Redirect the user to the login page for authentication.
+ */
+ protected void authenticateUser() {
+ Configuration conf = (Configuration) GWT.create(Configuration.class);
+ Window.Location.assign(GWT.getModuleBaseURL() + conf.loginUrl() + "?next=" + GWT.getModuleBaseURL());
+ }
+
+ /**
+ * Clear the cookie and redirect the user to the logout page.
+ */
+ void logout() {
+ Configuration conf = (Configuration) GWT.create(Configuration.class);
+ String cookie = conf.authCookie();
+ String domain = Window.Location.getHostName();
+ String path = Window.Location.getPath();
+ Cookies.setCookie(cookie, "", null, domain, path, false);
+ String baseUrl = GWT.getModuleBaseURL();
+ String homeUrl = baseUrl.substring(0, baseUrl.indexOf(path));
+ Window.Location.assign(homeUrl + conf.logoutUrl());
+ }
+
+ /**
+ * Creates an HTML fragment that places an image & caption together, for use
+ * in a group header.
+ *
+ * @param imageProto an image prototype for an image
+ * @param caption the group caption
+ * @return the header HTML fragment
+ */
+ private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
+ String captionHTML = "<table class='caption' cellpadding='0' "
+ + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML()
+ + "</td><td id =" + caption +" class='rcaption'><b style='white-space:nowrap'> "
+ + caption + "</b></td></tr></table>";
+ return captionHTML;
+ }
+
+ private void onWindowResized(int height) {
+ // Adjust the split panel to take up the available room in the window.
+ int newHeight = height - splitPanel.getAbsoluteTop() - 44;
+ if (newHeight < 1)
+ newHeight = 1;
+ splitPanel.setHeight("" + newHeight);
+ inner.setHeight("" + newHeight);
+ /*if(isFileListShowing()){
+ getFileList().setHeight("" + (newHeight-50));
+ }*/
+ }
+
+ @Override
+ public void onResize(ResizeEvent event) {
+ int height = event.getHeight();
+ onWindowResized(height);
+ }
+
+ public boolean isFileListShowing() {
+ int tab = inner.getTabBar().getSelectedTab();
+ if (tab == 0)
+ return true;
+ return false;
+ }
+
+ public boolean isSearchResultsShowing() {
+ int tab = inner.getTabBar().getSelectedTab();
+ if (tab == 2)
+ return true;
+ return false;
+ }
+
+ /**
+ * Make the user list visible.
+ */
+ public void showUserList() {
+ inner.selectTab(1);
+ }
+
+ /**
+ * Make the file list visible.
+ */
+ public void showFileList() {
+ fileList.updateFileCache(true /*clear selection*/);
+ inner.selectTab(0);
+ }
+
+ /**
+ * Make the file list visible.
+ *
+ * @param update
+ */
+ public void showFileList(boolean update) {
+ if(update){
+ getTreeView().refreshCurrentNode(true);
+ }
+ else{
+ RestResource currentFolder = getTreeView().getSelection();
+ if(currentFolder!=null){
+ showFileList(currentFolder);
+ }
+ }
+
+ }
+
+ public void showFileList(RestResource r) {
+ showFileList(r,true);
+ }
+
+ public void showFileList(RestResource r, boolean clearSelection) {
+ RestResource currentFolder = r;
+ if(currentFolder!=null){
+ List<FileResource> files = null;
+ if (currentFolder instanceof RestResourceWrapper) {
+ RestResourceWrapper folder = (RestResourceWrapper) currentFolder;
+ files = folder.getResource().getFiles();
+ } else if (currentFolder instanceof TrashResource) {
+ TrashResource folder = (TrashResource) currentFolder;
+ files = folder.getFiles();
+ }
+ else if (currentFolder instanceof SharedResource) {
+ SharedResource folder = (SharedResource) currentFolder;
+ files = folder.getFiles();
+ }
+ else if (currentFolder instanceof OtherUserResource) {
+ OtherUserResource folder = (OtherUserResource) currentFolder;
+ files = folder.getFiles();
+ }
+ if (files != null)
+ getFileList().setFiles(files);
+ else
+ getFileList().setFiles(new ArrayList<FileResource>());
+ }
+ fileList.updateFileCache(clearSelection /*clear selection*/);
+ inner.selectTab(0);
+ }
+
+ /**
+ * Make the search results visible.
+ *
+ * @param query the search query string
+ */
+ public void showSearchResults(String query) {
+ searchResults.updateFileCache(query);
+ searchResults.updateCurrentlyShowingStats();
+ inner.selectTab(2);
+ }
+
+ /**
+ * Display the 'loading' indicator.
+ */
+ public void showLoadingIndicator(String message, String path) {
+ if(path!=null){
+ String[] split = path.split("/");
+ message = message +" "+URL.decode(split[split.length-1]);
+ }
+ topPanel.getLoading().show(message);
+ }
+
+ /**
+ * Hide the 'loading' indicator.
+ */
+ public void hideLoadingIndicator() {
+ topPanel.getLoading().hide();
+ }
+
+ /**
+ * A native JavaScript method to reach out to the browser's window and
+ * invoke its resizeTo() method.
+ *
+ * @param x the new width
+ * @param y the new height
+ */
+ public static native void resizeTo(int x, int y) /*-{
+ $wnd.resizeTo(x,y);
+ }-*/;
+
+ /**
+ * A helper method that returns true if the user's list is currently visible
+ * and false if it is hidden.
+ *
+ * @return true if the user list is visible
+ */
+ public boolean isUserListVisible() {
+ return inner.getTabBar().getSelectedTab() == 1;
+ }
+
+ /**
+ * Display an error message.
+ *
+ * @param msg the message to display
+ */
+ public void displayError(String msg) {
+ messagePanel.displayError(msg);
+ }
+
+ /**
+ * Display a warning message.
+ *
+ * @param msg the message to display
+ */
+ public void displayWarning(String msg) {
+ messagePanel.displayWarning(msg);
+ }
+
+ /**
+ * Display an informational message.
+ *
+ * @param msg the message to display
+ */
+ public void displayInformation(String msg) {
+ messagePanel.displayInformation(msg);
+ }
+
+ /**
+ * Retrieve the folders.
+ *
+ * @return the folders
+
+ public Folders getFolders() {
+ return folders;
+ }*/
+
+ /**
+ * Retrieve the search.
+ *
+ * @return the search
+ */
+ Search getSearch() {
+ return search;
+ }
+
+ /**
+ * Retrieve the currentSelection.
+ *
+ * @return the currentSelection
+ */
+ public Object getCurrentSelection() {
+ return currentSelection;
+ }
+
+ /**
+ * Modify the currentSelection.
+ *
+ * @param newCurrentSelection the currentSelection to set
+ */
+ public void setCurrentSelection(Object newCurrentSelection) {
+ currentSelection = newCurrentSelection;
+ }
+
+ /**
+ * Retrieve the groups.
+ *
+ * @return the groups
+ */
+ public Groups getGroups() {
+ return groups;
+ }
+
+ /**
+ * Retrieve the fileList.
+ *
+ * @return the fileList
+ */
+ public FileList getFileList() {
+ return fileList;
+ }
+
+ public SearchResults getSearchResults() {
+ return searchResults;
+ }
+
+ /**
+ * Retrieve the topPanel.
+ *
+ * @return the topPanel
+ */
+ TopPanel getTopPanel() {
+ return topPanel;
+ }
+
+ /**
+ * Retrieve the clipboard.
+ *
+ * @return the clipboard
+ */
+ public Clipboard getClipboard() {
+ return clipboard;
+ }
+
+ public StatusPanel getStatusPanel() {
+ return statusPanel;
+ }
+
+ /**
+ * Retrieve the userDetailsPanel.
+ *
+ * @return the userDetailsPanel
+ */
+ public UserDetailsPanel getUserDetailsPanel() {
+ return userDetailsPanel;
+ }
+
+
+
+ public String getToken() {
+ return token;
+ }
+
+ public String getWebDAVPassword() {
+ return webDAVPassword;
+ }
+
+ public void removeGlassPanel() {
+ glassPanel.removeFromParent();
+ }
+
+ /**
+ * Retrieve the currentUserResource.
+ *
+ * @return the currentUserResource
+ */
+ public UserResource getCurrentUserResource() {
+ return currentUserResource;
+ }
+
+ /**
+ * Modify the currentUserResource.
+ *
+ * @param newUser the new currentUserResource
+ */
+ public void setCurrentUserResource(UserResource newUser) {
+ currentUserResource = newUser;
+ }
+
+ public static native void preventIESelection() /*-{
+ $doc.body.onselectstart = function () { return false; };
+ }-*/;
+
+ public static native void enableIESelection() /*-{
+ if ($doc.body.onselectstart != null)
+ $doc.body.onselectstart = null;
+ }-*/;
+
+ /**
+ * @return the absolute path of the API root URL
+ */
+ public String getApiPath() {
+ Configuration conf = (Configuration) GWT.create(Configuration.class);
+ return GWT.getModuleBaseURL() + conf.apiPath();
+ }
+
+ public void refreshWebDAVPassword() {
+ Configuration conf = (Configuration) GWT.create(Configuration.class);
+ String domain = Window.Location.getHostName();
+ String path = Window.Location.getPath();
+ String cookie = conf.webdavCookie();
+ webDAVPassword = Cookies.getCookie(cookie);
+ Cookies.setCookie(cookie, "", null, domain, path, false);
+ }
+
+ /**
+ * Convert server date to local time according to browser timezone
+ * and format it according to localized pattern.
+ * Time is always formatted to 24hr format.
+ * NB: This assumes that server runs in UTC timezone. Otherwise
+ * we would need to adjust for server time offset as well.
+ *
+ * @param date
+ * @return String
+ */
+ public static String formatLocalDateTime(Date date) {
+ Date convertedDate = new Date(date.getTime() - date.getTimezoneOffset());
+ final DateTimeFormat dateFormatter = DateTimeFormat.getShortDateFormat();
+ final DateTimeFormat timeFormatter = DateTimeFormat.getFormat("HH:mm");
+ String datePart = dateFormatter.format(convertedDate);
+ String timePart = timeFormatter.format(convertedDate);
+ return datePart + " " + timePart;
+ }
+
+ /**
+ * History support for folder navigation
+ * adds a new browser history entry
+ *
+ * @param key
+ */
+ public void updateHistory(String key){
+// Replace any whitespace of the initial string to "+"
+// String result = key.replaceAll("\\s","+");
+// Add a new browser history entry.
+// History.newItem(result);
+ History.newItem(key);
+ }
+
+ /**
+ * This method examines the token input and add a "/" at the end in case it's omitted.
+ * This happens only in Files/trash/, Files/shared/, Files/others.
+ *
+ * @param tokenInput
+ * @return the formated token with a "/" at the end or the same tokenInput parameter
+ */
+
+ private String handleSpecialFolderNames(String tokenInput){
+ List<String> pathsToCheck = Arrays.asList("Files/trash", "Files/shared", "Files/others");
+ if(pathsToCheck.contains(tokenInput))
+ return tokenInput + "/";
+ return tokenInput;
+
+ }
+
+ /**
+ * Reject illegal resource names, like '.' or '..' or slashes '/'.
+ */
+ static boolean isValidResourceName(String name) {
+ if (".".equals(name) || "..".equals(name) || name.contains("/"))
+ return false;
+ return true;
+ }
+
+ public void putUserToMap(String _userName, String _userFullName){
+ userFullNameMap.put(_userName, _userFullName);
+ }
+
+ public String findUserFullName(String _userName){
+ return userFullNameMap.get(_userName);
+ }
+ public String getUserFullName(String _userName) {
+
+ if (GSS.get().findUserFullName(_userName) == null)
+ //if there is no userFullName found then the map fills with the given _userName,
+ //so userFullName = _userName
+ GSS.get().putUserToMap(_userName, _userName);
+ else if(GSS.get().findUserFullName(_userName).indexOf('@') != -1){
+ //if the userFullName = _userName the GetUserCommand updates the userFullName in the map
+ GetUserCommand guc = new GetUserCommand(_userName);
+ guc.execute();
+ }
+ return GSS.get().findUserFullName(_userName);
+ }
+ /**
+ * Retrieve the treeView.
+ *
+ * @return the treeView
+ */
+ public CellTreeView getTreeView() {
+ return treeView;
+ }
+
+ public void onResourceUpdate(RestResource resource,boolean clearSelection){
+ if(resource instanceof RestResourceWrapper || resource instanceof OtherUserResource || resource instanceof TrashResource || resource instanceof SharedResource){
+ if(getTreeView().getSelection()!=null&&getTreeView().getSelection().getUri().equals(resource.getUri()))
+ showFileList(resource,clearSelection);
+ }
+
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+
+/**
+ * @author kman
+ *
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.InputElement;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.view.client.CellPreviewEvent;
+import com.google.gwt.view.client.HasData;
+import com.google.gwt.view.client.MultiSelectionModel;
+import com.google.gwt.view.client.Range;
+import com.google.gwt.view.client.SelectionModel;
+
+/**
+ * An implementation of {@link CellPreviewEvent.Handler} that adds selection
+ * support via the spacebar and mouse clicks and handles the control key.
+ *
+ * <p>
+ * If the {@link HasData} source of the selection event uses a
+ * {@link MultiSelectionModel}, this manager additionally provides support for
+ * shift key to select a range of values. For all other {@link SelectionModel}s,
+ * only the control key is supported.
+ * </p>
+ *
+ * @param <T> the data type of records in the list
+ */
+public class GSSSelectionEventManager<T> implements
+ CellPreviewEvent.Handler<T> {
+
+ /**
+ * Implementation of {@link EventTranslator} that only triggers selection when
+ * any checkbox is selected.
+ *
+ * @param <T> the data type
+ */
+ public static class CheckboxEventTranslator<T> implements EventTranslator<T> {
+
+ /**
+ * The column index of the checkbox. Other columns are ignored.
+ */
+ private final int column;
+
+ /**
+ * Construct a new {@link CheckboxEventTranslator} that will trigger
+ * selection when any checkbox in any column is selected.
+ */
+ public CheckboxEventTranslator() {
+ this(-1);
+ }
+
+ /**
+ * Construct a new {@link CheckboxEventTranslator} that will trigger
+ * selection when a checkbox in the specified column is selected.
+ *
+ * @param column the column index, or -1 for all columns
+ */
+ public CheckboxEventTranslator(int column) {
+ this.column = column;
+ }
+
+ public boolean clearCurrentSelection(CellPreviewEvent<T> event) {
+ return false;
+ }
+
+ public SelectAction translateSelectionEvent(CellPreviewEvent<T> event) {
+ // Handle the event.
+ NativeEvent nativeEvent = event.getNativeEvent();
+ if ("click".equals(nativeEvent.getType())) {
+ // Ignore if the event didn't occur in the correct column.
+ if (column > -1 && column != event.getColumn()) {
+ return SelectAction.IGNORE;
+ }
+
+ // Determine if we clicked on a checkbox.
+ Element target = nativeEvent.getEventTarget().cast();
+ if ("input".equals(target.getTagName().toLowerCase())) {
+ final InputElement input = target.cast();
+ if ("checkbox".equals(input.getType().toLowerCase())) {
+ // Synchronize the checkbox with the current selection state.
+ input.setChecked(event.getDisplay().getSelectionModel().isSelected(
+ event.getValue()));
+ return SelectAction.TOGGLE;
+ }
+ }
+ return SelectAction.IGNORE;
+ }
+
+ // For keyboard events, do the default action.
+ return SelectAction.DEFAULT;
+ }
+ }
+
+ /**
+ * Translates {@link CellPreviewEvent}s into {@link SelectAction}s.
+ */
+ public static interface EventTranslator<T> {
+ /**
+ * Check whether a user selection event should clear all currently selected
+ * values.
+ *
+ * @param event the {@link CellPreviewEvent} to translate
+ */
+ boolean clearCurrentSelection(CellPreviewEvent<T> event);
+
+ /**
+ * Translate the user selection event into a {@link SelectAction}.
+ *
+ * @param event the {@link CellPreviewEvent} to translate
+ */
+ SelectAction translateSelectionEvent(CellPreviewEvent<T> event);
+ }
+
+ /**
+ * The action that controls how selection is handled.
+ */
+ public static enum SelectAction {
+ DEFAULT, // Perform the default action.
+ SELECT, // Select the value.
+ DESELECT, // Deselect the value.
+ TOGGLE, // Toggle the selected state of the value.
+ IGNORE; // Ignore the event.
+ }
+
+ /**
+ * Construct a new {@link GSSSelectionEventManager} that triggers
+ * selection when any checkbox in any column is clicked.
+ *
+ * @param <T> the data type of the display
+ * @return a {@link GSSSelectionEventManager} instance
+ */
+ public static <T> GSSSelectionEventManager<T> createCheckboxManager() {
+ return new GSSSelectionEventManager<T>(new CheckboxEventTranslator<T>());
+ }
+
+ /**
+ * Construct a new {@link GSSSelectionEventManager} that triggers
+ * selection when a checkbox in the specified column is clicked.
+ *
+ * @param <T> the data type of the display
+ * @param column the column to handle
+ * @return a {@link GSSSelectionEventManager} instance
+ */
+ public static <T> GSSSelectionEventManager<T> createCheckboxManager(
+ int column) {
+ return new GSSSelectionEventManager<T>(new CheckboxEventTranslator<T>(
+ column));
+ }
+
+ /**
+ * Create a new {@link GSSSelectionEventManager} using the specified
+ * {@link EventTranslator} to control which {@link SelectAction} to take for
+ * each event.
+ *
+ * @param <T> the data type of the display
+ * @param translator the {@link EventTranslator} to use
+ * @return a {@link GSSSelectionEventManager} instance
+ */
+ public static <T> GSSSelectionEventManager<T> createCustomManager(
+ EventTranslator<T> translator) {
+ return new GSSSelectionEventManager<T>(translator);
+ }
+
+ /**
+ * Create a new {@link GSSSelectionEventManager} that handles selection
+ * via user interactions.
+ *
+ * @param <T> the data type of the display
+ * @return a new {@link GSSSelectionEventManager} instance
+ */
+ public static <T> GSSSelectionEventManager<T> createDefaultManager() {
+ return new GSSSelectionEventManager<T>(null);
+ }
+
+ /**
+ * The last {@link HasData} that was handled.
+ */
+ private HasData<T> lastDisplay;
+
+ /**
+ * The last page start.
+ */
+ private int lastPageStart;
+
+ /**
+ * The last selected row index.
+ */
+ private int lastSelectedIndex = -1;
+
+ /**
+ * A boolean indicating that the last shift selection was additive.
+ */
+ private boolean shiftAdditive;
+
+ /**
+ * The last place where the user clicked without holding shift. Multi
+ * selections that use the shift key are rooted at the anchor.
+ */
+ private int shiftAnchor = -1;
+
+ /**
+ * The {@link EventTranslator} that controls how selection is handled.
+ */
+ private final EventTranslator<T> translator;
+
+ /**
+ * Construct a new {@link GSSSelectionEventManager} using the specified
+ * {@link EventTranslator} to control which {@link SelectAction} to take for
+ * each event.
+ *
+ * @param translator the {@link EventTranslator} to use
+ */
+ protected GSSSelectionEventManager(EventTranslator<T> translator) {
+ this.translator = translator;
+ }
+
+ /**
+ * Update the selection model based on a user selection event.
+ *
+ * @param selectionModel the selection model to update
+ * @param row the selected row index relative to the page start
+ * @param rowValue the selected row value
+ * @param action the {@link SelectAction} to apply
+ * @param selectRange true to select the range from the last selected row
+ * @param clearOthers true to clear the current selection
+ */
+ public void doMultiSelection(MultiSelectionModel<? super T> selectionModel,
+ HasData<T> display, int row, T rowValue, SelectAction action,
+ boolean selectRange, boolean clearOthers) {
+ // Determine if we will add or remove selection.
+ boolean addToSelection = true;
+ if (action != null) {
+ switch (action) {
+ case IGNORE:
+ // Ignore selection.
+ return;
+ case SELECT:
+ addToSelection = true;
+ break;
+ case DESELECT:
+ addToSelection = false;
+ break;
+ case TOGGLE:
+ addToSelection = !selectionModel.isSelected(rowValue);
+ break;
+ }
+ }
+
+ // Determine which rows will be newly selected.
+ int pageStart = display.getVisibleRange().getStart();
+ if (selectRange && pageStart == lastPageStart && lastSelectedIndex > -1
+ && shiftAnchor > -1 && display == lastDisplay) {
+ /*
+ * Get the new shift bounds based on the existing shift anchor and the
+ * selected row.
+ */
+ int start = Math.min(shiftAnchor, row); // Inclusive.
+ int end = Math.max(shiftAnchor, row); // Inclusive.
+
+ if (lastSelectedIndex < start) {
+ // Revert previous selection if the user reselects a smaller range.
+ setRangeSelection(selectionModel, display, new Range(lastSelectedIndex,
+ start - lastSelectedIndex), !shiftAdditive, false);
+ } else if (lastSelectedIndex > end) {
+ // Revert previous selection if the user reselects a smaller range.
+ setRangeSelection(selectionModel, display, new Range(end + 1,
+ lastSelectedIndex - end), !shiftAdditive, false);
+ } else {
+ // Remember if we are adding or removing rows.
+ shiftAdditive = addToSelection;
+ }
+
+ // Update the last selected row, but do not move the shift anchor.
+ lastSelectedIndex = row;
+
+ // Select the range.
+ setRangeSelection(selectionModel, display, new Range(start, end - start
+ + 1), shiftAdditive, clearOthers);
+ } else {
+ /*
+ * If we are not selecting a range, save the last row and set the shift
+ * anchor.
+ */
+ lastDisplay = display;
+ lastPageStart = pageStart;
+ lastSelectedIndex = row;
+ shiftAnchor = row;
+ selectOne(selectionModel, rowValue, addToSelection, clearOthers);
+ }
+ }
+
+ public void onCellPreview(CellPreviewEvent<T> event) {
+ // Early exit if selection is already handled or we are editing.
+ if (event.isCellEditing() || event.isSelectionHandled()) {
+ return;
+ }
+
+ // Early exit if we do not have a SelectionModel.
+ HasData<T> display = event.getDisplay();
+ SelectionModel<? super T> selectionModel = display.getSelectionModel();
+ if (selectionModel == null) {
+ return;
+ }
+
+ // Check for user defined actions.
+ SelectAction action = (translator == null) ? SelectAction.DEFAULT
+ : translator.translateSelectionEvent(event);
+
+ // Handle the event based on the SelectionModel type.
+ if (selectionModel instanceof MultiSelectionModel) {
+ // Add shift key support for MultiSelectionModel.
+ handleMultiSelectionEvent(event, action,
+ (MultiSelectionModel<? super T>) selectionModel);
+ } else {
+ // Use the standard handler.
+ handleSelectionEvent(event, action, selectionModel);
+ }
+ }
+
+ /**
+ * Removes all items from the selection.
+ *
+ * @param selectionModel the {@link MultiSelectionModel} to clear
+ */
+ protected void clearSelection(MultiSelectionModel<? super T> selectionModel) {
+ selectionModel.clear();
+ }
+
+ /**
+ * Handle an event that could cause a value to be selected for a
+ * {@link MultiSelectionModel}. This overloaded method adds support for both
+ * the control and shift keys. If the shift key is held down, all rows between
+ * the previous selected row and the current row are selected.
+ *
+ * @param event the {@link CellPreviewEvent} that triggered selection
+ * @param action the action to handle
+ * @param selectionModel the {@link SelectionModel} to update
+ */
+ protected void handleMultiSelectionEvent(CellPreviewEvent<T> event,
+ SelectAction action, MultiSelectionModel<? super T> selectionModel) {
+ NativeEvent nativeEvent = event.getNativeEvent();
+ String type = nativeEvent.getType();
+ boolean rightclick = "mousedown".equals(type) && nativeEvent.getButton()==NativeEvent.BUTTON_RIGHT;
+ if(rightclick){
+ boolean shift = nativeEvent.getShiftKey();
+ boolean ctrlOrMeta = nativeEvent.getCtrlKey() || nativeEvent.getMetaKey();
+ boolean clearOthers = (translator == null) ? !ctrlOrMeta
+ : translator.clearCurrentSelection(event);
+ if (action == null || action == SelectAction.DEFAULT) {
+ action = ctrlOrMeta ? SelectAction.TOGGLE : SelectAction.SELECT;
+ }
+ //if the row is selected then do nothing
+ if(selectionModel.isSelected(event.getValue())){
+ return;
+ }
+ doMultiSelection(selectionModel, event.getDisplay(), event.getIndex(),
+ event.getValue(), action, shift, clearOthers);
+ }
+ else if ("click".equals(type)) {
+ /*
+ * Update selection on click. Selection is toggled only if the user
+ * presses the ctrl key. If the user does not press the control key,
+ * selection is additive.
+ */
+ boolean shift = nativeEvent.getShiftKey();
+ boolean ctrlOrMeta = nativeEvent.getCtrlKey() || nativeEvent.getMetaKey();
+ boolean clearOthers = (translator == null) ? !ctrlOrMeta
+ : translator.clearCurrentSelection(event);
+ if (action == null || action == SelectAction.DEFAULT) {
+ action = ctrlOrMeta ? SelectAction.TOGGLE : SelectAction.SELECT;
+ }
+ doMultiSelection(selectionModel, event.getDisplay(), event.getIndex(),
+ event.getValue(), action, shift, clearOthers);
+ if(ctrlOrMeta){
+ event.setCanceled(true);
+ }
+ } else if ("keyup".equals(type)) {
+ int keyCode = nativeEvent.getKeyCode();
+ if (keyCode == 32) {
+ /*
+ * Update selection when the space bar is pressed. The spacebar always
+ * toggles selection, regardless of whether the control key is pressed.
+ */
+ boolean shift = nativeEvent.getShiftKey();
+ boolean clearOthers = (translator == null) ? false
+ : translator.clearCurrentSelection(event);
+ if (action == null || action == SelectAction.DEFAULT) {
+ action = SelectAction.TOGGLE;
+ }
+ doMultiSelection(selectionModel, event.getDisplay(), event.getIndex(),
+ event.getValue(), action, shift, clearOthers);
+ }
+ }
+ }
+
+ /**
+ * Handle an event that could cause a value to be selected. This method works
+ * for any {@link SelectionModel}. Pressing the space bar or ctrl+click will
+ * toggle the selection state. Clicking selects the row if it is not selected.
+ *
+ * @param event the {@link CellPreviewEvent} that triggered selection
+ * @param action the action to handle
+ * @param selectionModel the {@link SelectionModel} to update
+ */
+ protected void handleSelectionEvent(CellPreviewEvent<T> event,
+ SelectAction action, SelectionModel<? super T> selectionModel) {
+ // Handle selection overrides.
+ T value = event.getValue();
+ if (action != null) {
+ switch (action) {
+ case IGNORE:
+ return;
+ case SELECT:
+ selectionModel.setSelected(value, true);
+ return;
+ case DESELECT:
+ selectionModel.setSelected(value, false);
+ return;
+ case TOGGLE:
+ selectionModel.setSelected(value, !selectionModel.isSelected(value));
+ return;
+ }
+ }
+
+ // Handle default selection.
+ NativeEvent nativeEvent = event.getNativeEvent();
+ String type = nativeEvent.getType();
+ if ("click".equals(type)) {
+ if (nativeEvent.getCtrlKey() || nativeEvent.getMetaKey()) {
+ // Toggle selection on ctrl+click.
+ selectionModel.setSelected(value, !selectionModel.isSelected(value));
+ } else {
+ // Select on click.
+ selectionModel.setSelected(value, true);
+ }
+ } else if ("keyup".equals(type)) {
+ // Toggle selection on space.
+ int keyCode = nativeEvent.getKeyCode();
+ if (keyCode == 32) {
+ selectionModel.setSelected(value, !selectionModel.isSelected(value));
+ }
+ }
+ }
+
+ /**
+ * Selects the given item, optionally clearing any prior selection.
+ *
+ * @param selectionModel the {@link MultiSelectionModel} to update
+ * @param target the item to select
+ * @param selected true to select, false to deselect
+ * @param clearOthers true to clear all other selected items
+ */
+ protected void selectOne(MultiSelectionModel<? super T> selectionModel,
+ T target, boolean selected, boolean clearOthers) {
+ if (clearOthers) {
+ clearSelection(selectionModel);
+ }
+ selectionModel.setSelected(target, selected);
+ }
+
+ /**
+ * Select or deselect a range of row indexes, optionally deselecting all other
+ * values.
+ *
+ * @param selectionModel the {@link MultiSelectionModel} to update
+ * @param display the {@link HasData} source of the selection event
+ * @param range the {@link Range} of rows to select or deselect
+ * @param addToSelection true to select, false to deselect the range
+ * @param clearOthers true to deselect rows not in the range
+ */
+ protected void setRangeSelection(
+ MultiSelectionModel<? super T> selectionModel, HasData<T> display,
+ Range range, boolean addToSelection, boolean clearOthers) {
+ // Get the list of values to select.
+ List<T> toUpdate = new ArrayList<T>();
+ int itemCount = display.getVisibleItemCount();
+ int start = range.getStart();
+ int end = start + range.getLength();
+ for (int i = start; i < end ; i++) {
+ toUpdate.add(display.getVisibleItem(i-display.getVisibleRange().getStart()));
+ }
+ // Clear all other values.
+ if (clearOthers) {
+ clearSelection(selectionModel);
+ }
+
+ // Update the state of the values.
+ for (T value : toUpdate) {
+ selectionModel.setSelected(value, addToSelection);
+ }
+ }
+}
+
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.SimplePanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GlassPanel extends Composite{
+
+ public GlassPanel(){
+ SimplePanel mySimplePanel = new SimplePanel();
+ initWidget(mySimplePanel);
+ setStyleName("gwt-GlassPanel");
+ setWidth("100%");
+ setHeight("100%");
+ }
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.Groups.Images;
+import org.gss_project.gss.web.client.commands.CopyCommand;
+import org.gss_project.gss.web.client.commands.DeleteUserOrGroupCommand;
+import org.gss_project.gss.web.client.commands.NewGroupCommand;
+import org.gss_project.gss.web.client.commands.NewUserCommand;
+import org.gss_project.gss.web.client.commands.PasteCommand;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.TreeItem;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GroupContextMenu extends PopupPanel {
+
+ /**
+ * The widget's images.
+ */
+ private final Images images;
+ private MenuItem copy;
+ private MenuItem paste;
+ private MenuItem newGroup;
+ private MenuItem addUser;
+ private MenuItem delete;
+ public GroupContextMenu(final Images newImages) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(true);
+ images=newImages;
+ setAnimationEnabled(true);
+ final MenuBar contextMenu = new MenuBar(true);
+ newGroup = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.groupNew()).getHTML() + " New Group</span>", true, new NewGroupCommand(this));
+ newGroup.getElement().setId("groupContextMenu.newGroup");
+ contextMenu.addItem(newGroup);
+
+ addUser = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.groupNew()).getHTML() + " Add User</span>", true, new NewUserCommand(this));
+ addUser.getElement().setId("groupContextMenu.addUser");
+ contextMenu.addItem(addUser);
+
+ copy = new MenuItem("<span id=groupContextMenu.copyUser>" + AbstractImagePrototype.create(newImages.copy()).getHTML() + " Copy User</span>", true, new CopyCommand(this));
+ copy.getElement().setId("groupContextMenu.copyUser");
+ contextMenu.addItem(copy);
+
+ paste = new MenuItem("<span id=groupContextMenu.pasteUser>" + AbstractImagePrototype.create(newImages.paste()).getHTML() + " Paste User</span>", true, new PasteCommand(this));
+ paste.getElement().setId("groupContextMenu.pasteUser");
+ contextMenu.addItem(paste);
+
+ delete = new MenuItem("<span id=groupContextMenu.delete>" + AbstractImagePrototype.create(newImages.delete()).getHTML() + " Delete</span>", true, new DeleteUserOrGroupCommand(this,images));
+ delete.getElement().setId("groupContextMenu.delete");
+ contextMenu.addItem(delete);
+
+ add(contextMenu);
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.google.gwt.user.client.ui.PopupPanel#show()
+ */
+ @Override
+ public void show() {
+ TreeItem current = GSS.get().getGroups().getCurrent();
+ if(current==null){
+ copy.setVisible(false);
+ paste.setVisible(false);
+ addUser.setVisible(false);
+ delete.setVisible(false);
+ }
+ else{
+ newGroup.setVisible(false);
+ if(current.getUserObject() instanceof GroupUserResource && GSS.get().getCurrentSelection() instanceof GroupUserResource)
+ copy.setVisible(true);
+ else
+ copy.setVisible(false);
+ if(current.getUserObject() instanceof GroupResource && GSS.get().getCurrentSelection() instanceof GroupResource && GSS.get().getClipboard().hasUserItem())
+ paste.setVisible(true);
+ else
+ paste.setVisible(false);
+ }
+ super.show();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.commands.NewGroupCommand;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * The 'Group' menu implementation.
+ */
+public class GroupMenu extends PopupPanel implements ClickHandler {
+ /**
+ * The widget's images.
+ */
+ private Images images;
+ private final MenuBar contextMenu;
+
+ /**
+ * An image bundle for this widgets images.
+ */
+ public interface Images extends ClientBundle {
+ @Source("org/gss_project/gss/resources/groupevent.png")
+ ImageResource groupNew();
+
+ @Source("org/gss_project/gss/resources/view_text.png")
+ ImageResource viewText();
+
+ }
+
+ /**
+ * The widget's constructor.
+ *
+ * @param newImages the image bundle passed on by the parent object
+ */
+ public GroupMenu(final Images newImages) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(true);
+ setAnimationEnabled(true);
+ images = newImages;
+
+ contextMenu = new MenuBar(true);
+ MenuItem newGroupItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.groupNew()).getHTML() + " New Group</span>", true, new NewGroupCommand(this));
+ newGroupItem.getElement().setId("topMenu.group.newGroup");
+ contextMenu.addItem(newGroupItem);
+
+ add(contextMenu);
+ }
+
+ @Override
+ public void onClick(ClickEvent event) {
+ GroupMenu menu = new GroupMenu(images);
+ int left = event.getRelativeElement().getAbsoluteLeft();
+ int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight();
+ menu.setPopupPosition(left, top);
+
+ menu.show();
+ }
+
+ /**
+ * Retrieve the contextMenu.
+ *
+ * @return the contextMenu
+ */
+ public MenuBar getContextMenu() {
+ contextMenu.setAutoOpen(false);
+ return contextMenu;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.Grid;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+/**
+ * @author kman
+ */
+public class GroupPropertiesDialog extends DialogBox {
+
+ /**
+ * The widget that holds the folderName of the folder.
+ */
+ private TextBox groupName = new TextBox();
+
+ /**
+ * A flag that denotes whether the dialog will be used to create or modify a
+ * folder.
+ */
+ private final boolean create;
+
+ /**
+ * The widget's constructor.
+ *
+ * @param _create true if the dialog is displayed for creating a new
+ * sub-folder of the selected folder, false if it is displayed
+ * for modifying the selected folder
+ */
+ public GroupPropertiesDialog(final boolean _create) {
+ setAnimationEnabled(true);
+ create = _create;
+ // Use this opportunity to set the dialog's caption.
+ if (create)
+ setText("Create Group");
+ else
+ setText("Group properties");
+ final VerticalPanel panel = new VerticalPanel();
+ setWidget(panel);
+ groupName.getElement().setId("groupDialog.textBox.name");
+ final Grid generalTable = new Grid(1, 2);
+ generalTable.setText(0, 0, "Group Name");
+ generalTable.setWidget(0, 1, groupName);
+ generalTable.getCellFormatter().setStyleName(0, 0, "props-labels");
+ generalTable.getCellFormatter().setStyleName(0, 1, "props-values");
+ generalTable.setCellSpacing(4);
+
+ panel.add(generalTable);
+ final HorizontalPanel buttons = new HorizontalPanel();
+ final Button ok = new Button("OK", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ createGroup(groupName.getText());
+ hide();
+ }
+ });
+ ok.getElement().setId("groupDialog.button.ok");
+ buttons.add(ok);
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);
+ // Create the 'Cancel' button, along with a listener that hides the
+ // dialog
+ // when the button is clicked.
+ final Button cancel = new Button("Cancel", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
+ cancel.getElement().setId("groupDialog.button.cancel");
+ buttons.add(cancel);
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
+ buttons.setSpacing(8);
+ buttons.addStyleName("gss-TabPanelBottom");
+ panel.add(buttons);
+ panel.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
+ //panel.addStyleName("gss-DialogBox");
+ panel.addStyleName("gss-TabPanelBottom");
+ }
+ @Override
+ public void center() {
+ super.center();
+ groupName.setFocus(true);
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when either
+ // enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ hide();
+ createGroup( groupName.getText());
+ break;
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ break;
+ }
+ }
+
+
+ /**
+ * Generate an RPC request to create a new group.
+ *
+ * @param userId the ID of the user whose namespace will be searched for
+ * groups
+ * @param aGroupName the name of the group to create
+ */
+ private void createGroup(String aGroupName) {
+
+ if (aGroupName == null || aGroupName.length() == 0) {
+ GSS.get().displayError("Empty group name!");
+ return;
+ }
+ GWT.log("createGroup(" + aGroupName + ")", null);
+ PostCommand cg = new PostCommand(GSS.get().getCurrentUserResource().getGroupsPath()+"?name="+URL.encodeComponent(aGroupName), "", 201){
+
+ @Override
+ public void onComplete() {
+ GSS.get().getGroups().updateGroups();
+ GSS.get().showUserList();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("Resource does not exist");
+ else if(statusCode == 409)
+ GSS.get().displayError("A group with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to create group:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error creating group:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cg);
+
+ }
+}
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.rest.GetCommand;\r
+import org.gss_project.gss.web.client.rest.MultipleGetCommand;\r
+import org.gss_project.gss.web.client.rest.resource.GroupResource;\r
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;\r
+import org.gss_project.gss.web.client.rest.resource.GroupsResource;\r
+\r
+import java.util.List;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.ContextMenuEvent;\r
+import com.google.gwt.event.dom.client.ContextMenuHandler;\r
+import com.google.gwt.event.logical.shared.OpenEvent;\r
+import com.google.gwt.event.logical.shared.OpenHandler;\r
+import com.google.gwt.event.logical.shared.SelectionEvent;\r
+import com.google.gwt.event.logical.shared.SelectionHandler;\r
+import com.google.gwt.resources.client.ClientBundle;\r
+import com.google.gwt.resources.client.ImageResource;\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.DeferredCommand;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.Composite;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.Tree;\r
+import com.google.gwt.user.client.ui.TreeItem;\r
+\r
+/**\r
+ * A component that displays a list of the user's groups.\r
+ */\r
+public class Groups extends Composite implements SelectionHandler, OpenHandler {\r
+\r
+ /**\r
+ * An image bundle for this widget.\r
+ */\r
+ public interface Images extends Tree.Resources, ClientBundle, FileMenu.Images, EditMenu.Images, GroupMenu.Images, MessagePanel.Images {\r
+\r
+ /**\r
+ * Will bundle the file 'groupevent.png' residing in the package\r
+ * 'org.gss_project.gss.web.resources'.\r
+ *\r
+ * @return the image prototype\r
+ */\r
+ @Source("org/gss_project/gss/resources/groupevent.png")\r
+ ImageResource groupImage();\r
+\r
+ @Override\r
+ @Source("org/gss_project/gss/resources/editdelete.png")\r
+ ImageResource delete();\r
+\r
+ }\r
+\r
+ /**\r
+ * cached latest group selection (for selecting and expanding on refresh)\r
+ */\r
+ private String selectedGroup = null;\r
+\r
+ /**\r
+ * The tree widget that displays the groups.\r
+ */\r
+ private Tree tree;\r
+\r
+ /**\r
+ * A cached copy of the currently selected group widget.\r
+ */\r
+ private TreeItem current;\r
+\r
+ /**\r
+ * A cached copy of the previously selected group widget.\r
+ */\r
+ private TreeItem previous;\r
+\r
+ /**\r
+ * The widget's image bundle.\r
+ */\r
+ private final Images images;\r
+\r
+ private GroupContextMenu menu;\r
+\r
+ /**\r
+ * Constructs a new groups widget with a bundle of images.\r
+ *\r
+ * @param newImages a bundle that provides the images for this widget\r
+ */\r
+ public Groups(final Images newImages) {\r
+\r
+ images = newImages;\r
+ menu = new GroupContextMenu(images);\r
+ tree = new Tree(newImages);\r
+ this.addHandler(new ContextMenuHandler() {\r
+\r
+ @Override\r
+ public void onContextMenu(ContextMenuEvent event) {\r
+ if(current==null) return;\r
+ int left = current.getAbsoluteLeft() + 40;\r
+ int top = current.getAbsoluteTop() + 20;\r
+ showPopup(left, top);\r
+\r
+ }\r
+ }, ContextMenuEvent.getType());\r
+ tree.getElement().setId("groupsList.tree");\r
+ tree.addSelectionHandler(this);\r
+ tree.addOpenHandler(this);\r
+ tree.setAnimationEnabled(true);\r
+ initWidget(tree);\r
+ this.getElement().setAttribute("id", "CreativeFilesPanel");\r
+ setStylePrimaryName("gss-Groups");\r
+ sinkEvents(Event.ONCONTEXTMENU);\r
+ sinkEvents(Event.ONMOUSEUP);\r
+ sinkEvents(Event.ONDBLCLICK);\r
+ sinkEvents(Event.KEYEVENTS);\r
+ }\r
+\r
+\r
+ /**\r
+ * Make an RPC call to retrieve the groups that belong to the specified\r
+ * user.\r
+ */\r
+ public void updateGroups() {\r
+ GetCommand<GroupsResource> gg = new GetCommand<GroupsResource>(GroupsResource.class, GSS.get().getCurrentUserResource().getGroupsPath(),null){\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ GroupsResource res = getResult();\r
+ MultipleGetCommand<GroupResource> ga = new MultipleGetCommand<GroupResource>(GroupResource.class, res.getGroupPaths().toArray(new String[]{}), null){\r
+\r
+ @Override\r
+ public void onComplete() {\r
+ List<GroupResource> groupList = getResult();\r
+ tree.clear();\r
+ for (int i = 0; i < groupList.size(); i++) {\r
+ final TreeItem item = new TreeItem();\r
+ item.setWidget(imageItemHTML(images.groupImage(), groupList.get(i).getName(),item));\r
+ item.setUserObject(groupList.get(i)); \r
+ tree.addItem(item);\r
+ updateUsers(item);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ }\r
+\r
+ @Override\r
+ public void onError(String p, Throwable throwable) {\r
+ GWT.log("Path:"+p, throwable);\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(ga);\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(gg);\r
+ }\r
+\r
+ /**\r
+ * update status panel with currently showing file stats\r
+ */\r
+ public void updateCurrentlyShowingStats() {\r
+ GSS.get().getStatusPanel().updateCurrentlyShowing(null); //clear stats - nothing to show for the groups tab\r
+ }\r
+\r
+ /**\r
+ * A helper method to simplify adding tree items that have attached images.\r
+ *\r
+ * @param parent the tree item to which the new item will be added.\r
+ * @param title the text associated with this item.\r
+ * @param imageProto\r
+ * @return the new tree item\r
+ */\r
+ private TreeItem addImageItem(final TreeItem parent, final String title, final ImageResource imageProto) {\r
+ final TreeItem item = new TreeItem();\r
+ item.setWidget(imageItemHTML(imageProto, title,item));\r
+ parent.addItem(item);\r
+ return item;\r
+ }\r
+\r
+ /**\r
+ * Generates HTML for a tree item with an attached icon.\r
+ *\r
+ * @param imageProto the icon image\r
+ * @param title the title of the item\r
+ * @return the resultant HTML\r
+ */\r
+ private HTML imageItemHTML(final ImageResource imageProto, final String title,final TreeItem item) {\r
+ final HTML link = new HTML("<a class='hidden-link' href='javascript:;'>" + "<span id='groupsList."+title+"'>" + AbstractImagePrototype.create(imageProto).getHTML() + " " + title + "</span>" + "</a>"){\r
+ @Override\r
+ public void onBrowserEvent(Event event) {\r
+ switch (DOM.eventGetType(event)) {\r
+ case Event.ONMOUSEDOWN:\r
+ if (DOM.eventGetButton(event) == NativeEvent.BUTTON_RIGHT || DOM.eventGetButton(event) == NativeEvent.BUTTON_LEFT)\r
+ onSelection(item);\r
+ break;\r
+ case Event.ONCONTEXTMENU:\r
+ showPopup(event.getClientX(), event.getClientY());\r
+ event.preventDefault();\r
+ event.stopPropagation();\r
+ break;\r
+ }\r
+ super.onBrowserEvent(event);\r
+\r
+ }\r
+ }; \r
+ link.sinkEvents(Event.ONMOUSEDOWN);\r
+ link.sinkEvents(Event.ONCONTEXTMENU);\r
+ link.sinkEvents(Event.ONCLICK);\r
+ link.sinkEvents(Event.ONKEYDOWN); \r
+ return link;\r
+ }\r
+\r
+\r
+\r
+ protected void showPopup(final int x, final int y) {\r
+ menu.hide();\r
+ menu = new GroupContextMenu(images);\r
+ menu.setPopupPosition(x, y);\r
+ menu.show();\r
+ }\r
+\r
+\r
+\r
+ /**\r
+ * Generate an RPC request to retrieve the users of the specified group for\r
+ * display.\r
+ *\r
+ * @param groupItem the TreeItem widget that corresponds to the requested\r
+ * group\r
+ */\r
+ void updateUsers(final TreeItem groupItem) {\r
+ if(groupItem.getUserObject() instanceof GroupResource){\r
+ GroupResource res = (GroupResource) groupItem.getUserObject();\r
+ MultipleGetCommand<GroupUserResource> gu = new MultipleGetCommand<GroupUserResource>(GroupUserResource.class, res.getUserPaths().toArray(new String[]{}), null){\r
+ @Override\r
+ public void onComplete() {\r
+ List<GroupUserResource> users = getResult();\r
+ groupItem.removeItems();\r
+ for (int i = 0; i < users.size(); i++) {\r
+ final TreeItem userItem = addImageItem(groupItem, users.get(i).getName() + " <" + users.get(i).getUsername() + ">", images.permUser());\r
+ userItem.setUserObject(users.get(i));\r
+ }\r
+ if (selectedGroup != null && groupItem.getText().equals(selectedGroup)) {\r
+ //SelectionEvent.fire(tree, groupItem);;\r
+ onSelection(groupItem);\r
+ groupItem.setState(true);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void onError(Throwable t) {\r
+ GWT.log("", t);\r
+ }\r
+\r
+ @Override\r
+ public void onError(String p, Throwable throwable) {\r
+ GWT.log("Path:"+p, throwable);\r
+ }\r
+ };\r
+ DeferredCommand.addCommand(gu);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Retrieve the current.\r
+ *\r
+ * @return the current\r
+ */\r
+ TreeItem getCurrent() {\r
+ return current;\r
+ }\r
+\r
+ /**\r
+ * Modify the current.\r
+ *\r
+ * @param newCurrent the current to set\r
+ */\r
+ void setCurrent(final TreeItem newCurrent) {\r
+ current = newCurrent;\r
+ }\r
+\r
+ /**\r
+ * Retrieve the previous.\r
+ *\r
+ * @return the previous\r
+ */\r
+ private TreeItem getPrevious() {\r
+ return previous;\r
+ }\r
+\r
+ /**\r
+ * Modify the previous.\r
+ *\r
+ * @param newPrevious the previous to set\r
+ */\r
+ private void setPrevious(final TreeItem newPrevious) {\r
+ previous = newPrevious;\r
+ }\r
+\r
+ @Override\r
+ public void setVisible(final boolean visible) {\r
+ super.setVisible(visible);\r
+ if (visible)\r
+ updateGroups();\r
+ }\r
+\r
+ @Override\r
+ public void onSelection(SelectionEvent event) {\r
+ final TreeItem item = (TreeItem)event.getSelectedItem();\r
+ onSelection(item);\r
+\r
+ }\r
+\r
+ private void onSelection(TreeItem item){\r
+ final Object selected = item.getUserObject();\r
+ // Preserve the previously selected item, so that the current's\r
+ // onClick() method gets a chance to find it.\r
+ if (getPrevious() != null)\r
+ getPrevious().getWidget().removeStyleName("gss-SelectedRow");\r
+ setCurrent(item);\r
+ getCurrent().getWidget().addStyleName("gss-SelectedRow");\r
+ setPrevious(getCurrent());\r
+ GSS.get().setCurrentSelection(selected);\r
+ //cache the latest top level node (group) for selecting and expanding on refresh\r
+ if (item.getParentItem() == null)\r
+ selectedGroup = item.getText();\r
+ else\r
+ selectedGroup = item.getParentItem().getText();\r
+ }\r
+\r
+ @Override\r
+ public void onOpen(OpenEvent event) {\r
+ final TreeItem item = (TreeItem) event.getTarget();\r
+ updateUsers(item);\r
+ }\r
+}\r
--- /dev/null
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+/* Incremental changes from CellTable.css */
+.cellTableFooter {
+ padding: 3px 9px;
+}
+
+.cellTableHeader {
+ /*padding: 3px 9px;*/
+ border:none;
+ background-color: #E0EDFE;
+ font-weight: bold;
+ cursor: pointer;
+}
+
+.cellTableCell {
+ padding: 4px 9px;
+ border-width: 0;
+}
+
+.cellTableFirstColumn {
+ padding: 0px;
+}
+
+.cellTableLastColumn {
+ padding: 0px;
+}
+
+.cellTableFirstColumnFooter {
+ border: 0px;
+ padding: 0px;
+}
+
+.cellTableFirstColumnHeader {
+ border: 0px;
+ padding: 0px;
+}
+
+.cellTableLastColumnFooter {
+ border: 0px;
+ padding: 0px;
+}
+
+.cellTableLastColumnHeader {
+ border: 0px;
+ padding: 0px;
+}
+
+.cellTableEvenRow {
+ cursor: hand;
+ cursor: pointer;
+}
+
+.cellTableOddRow {
+ cursor: hand;
+ cursor: pointer;
+}
+
+.cellTableSelectedRow {
+ background: #628cd5;
+ color: white;
+ height: auto;
+ overflow: auto;
+}
+
+ .cellTableHoveredRow {
+
+ /*background-color: #E0EDFE;
+ color: white;
+ height: auto;
+ overflow: auto;*/
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+.cellTreeWidget {
+
+}
+
+.cellTreeEmptyMessage {
+ padding-left: 16px;
+ font-style: italic;
+}
+
+.cellTreeItem {
+ padding-top: 4px;
+ padding-bottom: 4px;
+ cursor: hand;
+ cursor: pointer;
+ zoom: 1;
+}
+
+.cellTreeItemImage {
+
+}
+
+.cellTreeItemImageValue {
+ zoom: 1;
+}
+
+.cellTreeItemValue {
+ padding-left: 3px;
+ padding-right: 3px;
+ outline: none;
+}
+
+.cellTreeOpenItem {
+
+}
+
+.cellTreeTopItem {
+
+}
+
+.cellTreeTopItemImage {
+
+}
+
+.cellTreeTopItemImageValue {
+
+}
+
+.cellTreeKeyboardSelectedItem {
+ background-color: #ffc;
+ outline: none;
+}
+
+.cellTreeSelectedItem {
+ background-color: #628cd5;
+ color: white;
+ height: auto;
+ overflow: visible;
+}
+
+.cellTreeShowMoreButton {
+ padding-left: 16px;
+ outline: none;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * The 'Help' menu implementation.
+ */
+public class HelpMenu extends PopupPanel implements ClickHandler {
+
+ /**
+ * The widget's images.
+ */
+ private final Images images;
+
+ private MenuBar contextMenu = new MenuBar(true);
+
+ /**
+ * An image bundle for this widget's images.
+ */
+ public interface Images extends ClientBundle{
+ @Source("org/gss_project/gss/resources/khelpcenter.png")
+ ImageResource userGuide();
+
+ @Source("org/gss_project/gss/resources/linewidth.png")
+ ImageResource terms();
+
+ @Source("org/gss_project/gss/resources/bell.png")
+ ImageResource reportAbuse();
+
+ @Source("org/gss_project/gss/resources/bug.png")
+ ImageResource reportBug();
+
+ @Source("org/gss_project/gss/resources/info.png")
+ ImageResource about();
+
+ @Source("org/gss_project/gss/resources/edit_add.png")
+ ImageResource upgradeQuota();
+ }
+
+ /**
+ * The widget's constructor.
+ *
+ * @param newImages the image bundle passed on by the parent object
+ */
+ public HelpMenu(final Images newImages) {
+ // The popup's constructor's argument is a boolean specifying that it
+ // auto-close itself when the user clicks outside of it.
+ super(true);
+ setAnimationEnabled(true);
+ images = newImages;
+ createMenu();
+ add(contextMenu);
+ }
+
+ @Override
+ public void onClick(ClickEvent event) {
+ HelpMenu menu = new HelpMenu(images);
+ int left = event.getRelativeElement().getAbsoluteLeft();
+ int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight();
+ menu.setPopupPosition(left, top);
+ menu.show();
+ }
+
+ public MenuBar createMenu() {
+ contextMenu.clearItems();
+ contextMenu.setAutoOpen(false);
+ Command hideCommand = new Command() {
+ @Override
+ public void execute() {
+ hide();
+ }
+ };
+ Command aboutCommand = new Command(){
+ @Override
+ public void execute() {
+ AboutDialog dlg = new AboutDialog();
+ dlg.center();
+ }
+ };
+ MenuItem userGuideItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.userGuide()).getHTML() + " <a class='hidden-link' " +
+ "href='/userguide/el' target='_blank'>User Guide</a></span>", true, hideCommand);
+ contextMenu.addItem(userGuideItem);
+ userGuideItem.getElement().setId("topMenu.help.userGuide");
+
+ MenuItem termsItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.terms()).getHTML() + " <a class='hidden-link' " +
+ "href='/terms' target='_blank'>Terms & Conditions</a></span>", true, hideCommand);
+ termsItem.getElement().setId("topMenu.help.terms");
+ contextMenu.addItem(termsItem);
+
+ MenuItem reportAbuseItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.reportAbuse()).getHTML() + " <a class='hidden-link' " +
+ "href='/report-abuse' target='_blank'>Report abuse</a></span>", true, hideCommand);
+ reportAbuseItem.getElement().setId("topMenu.help.reportAbuse");
+ contextMenu.addItem(reportAbuseItem);
+
+ MenuItem upgradeQuotaItem= new MenuItem("<span>" + AbstractImagePrototype.create(images.upgradeQuota()).getHTML() + " <a class='hidden-link' " +
+ "href='/pithos/coupon' target='_blank'>Upgrade quota</a></span>", true, hideCommand);
+ upgradeQuotaItem.getElement().setId("topMenu.help.upgradeQuota");
+ contextMenu.addItem(upgradeQuotaItem);
+
+ MenuItem reportBugItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.reportBug()).getHTML() + " <a class='hidden-link' " +
+ "href='http://code.google.com/p/gss/issues/list' target='_blank'>Report bug</a></span>", true, hideCommand);
+ reportBugItem.getElement().setId("topMenu.help.reportBug");
+ contextMenu.addItem(reportBugItem);
+
+ MenuItem aboutItem = new MenuItem("<span>" + AbstractImagePrototype.create(images.about()).getHTML() + " About</span>", true, aboutCommand);
+ aboutItem.getElement().setId("topMenu.help.about");
+ contextMenu.addItem(aboutItem);
+ return contextMenu;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import java.io.Serializable;
+
+/**
+ * An exception that is thrown when an operation cannot be performed due to the
+ * user having insufficient permissions.
+ *
+ * @author chstath
+ */
+public class InsufficientPermissionsException extends Exception implements Serializable {
+
+ /**
+ * The serial version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The stored message that provides details about the problem.
+ */
+ private String message;
+
+ /**
+ *
+ */
+ public InsufficientPermissionsException() {
+ }
+
+ /**
+ * @param newMessage
+ */
+ public InsufficientPermissionsException(final String newMessage) {
+ super(newMessage);
+ message = newMessage;
+ }
+
+ /**
+ * @param cause
+ */
+ public InsufficientPermissionsException(final Throwable cause) {
+ super(cause);
+
+ }
+
+ /**
+ * @param newMessage
+ * @param cause
+ */
+ public InsufficientPermissionsException(final String newMessage, final Throwable cause) {
+ super(newMessage, cause);
+ message = newMessage;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import com.google.gwt.resources.client.ClientBundle;\r
+import com.google.gwt.resources.client.ImageResource;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.Composite;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'loading' indicator widget implementation.\r
+ */\r
+public class LoadingIndicator extends Composite {\r
+ public static final String DEFAULT_MESSAGE="Please Wait";\r
+ \r
+ HTML messageLabel;\r
+ /**\r
+ * An image bundle for this widgets images.\r
+ */\r
+ public interface Images extends ClientBundle {\r
+ @Source("org/gss_project/gss/resources/ajax-loader.gif")\r
+ ImageResource loading();\r
+ }\r
+\r
+ /**\r
+ * The widget's constructor that creates a spinning indicator image.\r
+ */\r
+ public LoadingIndicator(Images images) {\r
+ VerticalPanel vp = new VerticalPanel();\r
+ //vp.setHorizontalAlignment(HorizontalAlignmentConstant.CENTER);\r
+ HTML inner = new HTML(AbstractImagePrototype.create(images.loading()).getHTML());\r
+ vp.add(inner);\r
+ vp.add(messageLabel = new HTML(DEFAULT_MESSAGE) );\r
+ vp.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);\r
+ vp.setCellHorizontalAlignment(messageLabel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ initWidget(vp);\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Modify the message.\r
+ *\r
+ * @param message the message to set\r
+ */\r
+ public void setMessage(String message) {\r
+ messageLabel.setHTML(message);\r
+ }\r
+ \r
+ public void clearMessage(){\r
+ setMessage(DEFAULT_MESSAGE);\r
+ }\r
+ \r
+ public void show(String msg){\r
+ if(msg==null)\r
+ setMessage(DEFAULT_MESSAGE);\r
+ else\r
+ setMessage(msg);\r
+ this.setVisible(true);\r
+ }\r
+ \r
+ public void hide(){\r
+ setMessage(DEFAULT_MESSAGE);\r
+ this.setVisible(false);\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import org.gss_project.gss.web.client.animation.FadeIn;\r
+import org.gss_project.gss.web.client.animation.FadeOut;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.resources.client.ClientBundle;\r
+import com.google.gwt.resources.client.ImageResource;\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.Composite;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HasVerticalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.SimplePanel;\r
+\r
+/**\r
+ * A panel that displays various system messages.\r
+ */\r
+public class MessagePanel extends Composite {\r
+ /**\r
+ * An image bundle for this widget's images.\r
+ */\r
+ public interface Images extends ClientBundle {\r
+ @Source("org/gss_project/gss/resources/messagebox_info.png")\r
+ ImageResource info();\r
+\r
+ @Source("org/gss_project/gss/resources/messagebox_warning.png")\r
+ ImageResource warn();\r
+\r
+ @Source("org/gss_project/gss/resources/messagebox_critical.png")\r
+ ImageResource error();\r
+ }\r
+\r
+ /**\r
+ * The widget's images.\r
+ */\r
+ public static Images images;\r
+\r
+ /**\r
+ * The system message to be displayed.\r
+ */\r
+ private HTML message = new HTML(" ");\r
+\r
+ /**\r
+ * A link to clear the displayed message.\r
+ */\r
+ private HTML clearMessageLink = new HTML("<a class='gss-clearMessage' href='javascript:;'>Clear</a>");\r
+\r
+ /**\r
+ * The panel that contains the messages.\r
+ */\r
+ private HorizontalPanel inner = new HorizontalPanel();\r
+\r
+ /**\r
+ * The panel that enables special effects for this widget.\r
+ */\r
+ private SimplePanel simplePanel = new SimplePanel();\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ *\r
+ * @param newImages a bundle that provides the images for this widget\r
+ */\r
+ public MessagePanel(final Images newImages) {\r
+ images = newImages;\r
+ buildPanel();\r
+ simplePanel.setStyleName("effectPanel");\r
+ inner.setStyleName("effectPanel-inner");\r
+ DOM.setStyleAttribute(simplePanel.getElement(), "zoom", "1");\r
+ simplePanel.add(inner);\r
+ initWidget(simplePanel);\r
+ }\r
+\r
+ /**\r
+ * Build the panel that contains the icon, the message and the 'clear' link.\r
+ */\r
+ private void buildPanel() {\r
+ inner.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);\r
+ inner.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);\r
+ inner.setSpacing(4);\r
+ inner.add(message);\r
+ inner.add(clearMessageLink);\r
+ inner.setCellVerticalAlignment(message, HasVerticalAlignment.ALIGN_MIDDLE);\r
+ clearMessageLink.addClickHandler(new ClickHandler() {\r
+\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ FadeOut anim = new FadeOut(simplePanel){\r
+ @Override\r
+ protected void onComplete() {\r
+ super.onComplete();\r
+ hideMessage();\r
+ }\r
+ };\r
+ anim.run(500);\r
+ }\r
+ });\r
+ }\r
+\r
+ /**\r
+ * Display an error message.\r
+ *\r
+ * @param msg the message to display\r
+ */\r
+ public void displayError(final String msg) {\r
+ GWT.log(msg, null);\r
+ message = new HTML("<table class='gss-errorMessage'><tr><td>" + AbstractImagePrototype.create(images.error()).getHTML() + "</td><td>" + msg + "</td></tr></table>");\r
+ message.addClickHandler(new ClickHandler() {\r
+\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ FadeOut anim = new FadeOut(simplePanel){\r
+\r
+ @Override\r
+ protected void onComplete() {\r
+ super.onComplete();\r
+ hideMessage();\r
+ }\r
+ };\r
+ anim.run(500);\r
+ }\r
+ });\r
+ buildPanel();\r
+ setVisible(true);\r
+ FadeIn anim = new FadeIn(simplePanel);\r
+ anim.run(500);\r
+ }\r
+\r
+ /**\r
+ * Display a warning message.\r
+ *\r
+ * @param msg the message to display\r
+ */\r
+ public void displayWarning(final String msg) {\r
+ message = new HTML("<table class='gss-warnMessage'><tr><td>" + AbstractImagePrototype.create(images.warn()).getHTML() + "</td><td>" + msg + "</td></tr></table>");\r
+ message.addClickHandler(new ClickHandler() {\r
+\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ FadeOut anim = new FadeOut(simplePanel){\r
+\r
+ @Override\r
+ protected void onComplete() {\r
+ super.onComplete();\r
+ hideMessage();\r
+ }\r
+ };\r
+ anim.run(500);\r
+ }\r
+ });\r
+\r
+ buildPanel();\r
+ setVisible(true);\r
+ FadeIn anim = new FadeIn(simplePanel);\r
+ anim.run(500);\r
+ }\r
+\r
+ /**\r
+ * Display an informational message.\r
+ *\r
+ * @param msg the message to display\r
+ */\r
+ public void displayInformation(final String msg) {\r
+ message = new HTML("<table class='gss-infoMessage'><tr><td>" + AbstractImagePrototype.create(images.info()).getHTML() + "</td><td>" + msg + "</td></tr></table>");\r
+ message.addClickHandler(new ClickHandler() {\r
+\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ FadeOut anim = new FadeOut(simplePanel){\r
+\r
+ @Override\r
+ protected void onComplete() {\r
+ super.onComplete();\r
+ hideMessage();\r
+ }\r
+ };\r
+ anim.run(500);\r
+ }\r
+ });\r
+\r
+ buildPanel();\r
+ setVisible(true);\r
+ FadeIn anim = new FadeIn(simplePanel);\r
+ anim.run(500);\r
+ }\r
+\r
+ /**\r
+ * Clear the displayed message and hide the panel.\r
+ */\r
+ public void hideMessage() {\r
+ inner.clear();\r
+ message = new HTML(" ");\r
+ this.setVisible(false);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import java.io.Serializable;
+
+/**
+ * An exception thrown when a requested object was not found.
+ *
+ * @author past
+ */
+public class ObjectNotFoundException extends Exception implements Serializable {
+
+ /**
+ * The serial version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The stored message that provides details about the problem.
+ */
+ private String message;
+
+ /**
+ * Default constructor
+ */
+ public ObjectNotFoundException() {
+ super();
+ }
+
+ /**
+ * Constructor from error message.
+ *
+ * @param newMessage The error message
+ */
+ public ObjectNotFoundException(final String newMessage) {
+ super(newMessage);
+ message = newMessage;
+ }
+
+ /**
+ * Constructor from Throwable.
+ *
+ * @param cause The throwable that caused the exception
+ */
+ public ObjectNotFoundException(final Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructor from error message and Throwable.
+ *
+ * @param newMessage The error message
+ * @param cause The throwable that caused the exception
+ */
+ public ObjectNotFoundException(final String newMessage, final Throwable cause) {
+ super(newMessage, cause);
+ message = newMessage;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.PermissionHolder;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import org.gss_project.gss.web.client.rest.resource.UserSearchResource;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.KeyUpEvent;
+import com.google.gwt.event.dom.client.KeyUpHandler;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.CheckBox;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
+import com.google.gwt.user.client.ui.SuggestBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+/**
+ * @author kman
+ */
+public class PermissionsAddDialog extends DialogBox {
+
+ private MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
+ private SuggestBox suggestBox = new SuggestBox(oracle);
+
+ private String selectedUser = null;
+
+ private List<GroupResource> groups;
+
+ private ListBox groupBox = new ListBox();
+
+ private CheckBox read = new CheckBox();
+
+ private CheckBox write = new CheckBox();
+
+ private CheckBox modifyACL = new CheckBox();
+
+ private final PermissionsList permList;
+
+ boolean userAdd;
+
+ public PermissionsAddDialog(List<GroupResource> _groups, PermissionsList _permList, boolean _userAdd) {
+ groups = _groups;
+ userAdd = _userAdd;
+ permList = _permList;
+
+ groupBox.getElement().setId("addPermission.dropDown");
+
+ suggestBox.getElement().setId("addPermission.textBox");
+
+ read.getElement().setId("addPermission.read");
+
+ write.getElement().setId("addPermission.write");
+
+ modifyACL.getElement().setId("addpermission.modify");
+
+ for (GroupResource group : _groups)
+ groupBox.addItem(group.getName(), group.getName());
+ final VerticalPanel panel = new VerticalPanel();
+ final HorizontalPanel buttons = new HorizontalPanel();
+ setWidget(panel);
+ final FlexTable permTable = new FlexTable();
+ permTable.setText(0, 0, "Users/Groups");
+ permTable.setText(0, 1, "Read");
+ permTable.setText(0, 2, "Write");
+ permTable.setText(0, 3, "Modify Access");
+ permTable.getFlexCellFormatter().setStyleName(0, 0, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 1, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 2, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 3, "props-toplabels");
+ if (userAdd) {
+ suggestBox.getTextBox().addFocusHandler(new FocusHandler() {
+
+ @Override
+ public void onFocus(FocusEvent event) {
+ if (selectedUser != null && selectedUser.endsWith("@"))
+ updateSuggestions();
+
+ }
+ });
+
+ suggestBox.addKeyUpHandler(new KeyUpHandler() {
+
+ @Override
+ public void onKeyUp(KeyUpEvent event) {
+ // Ignore the arrow keys.
+ int keyCode = event.getNativeKeyCode();
+ if (keyCode == KeyCodes.KEY_UP ||
+ keyCode == KeyCodes.KEY_DOWN ||
+ keyCode == KeyCodes.KEY_LEFT ||
+ keyCode == KeyCodes.KEY_RIGHT)
+ return;
+ if (keyCode==KeyCodes.KEY_ESCAPE) {
+ suggestBox.hideSuggestionList();
+ return;
+ }
+ String text = suggestBox.getText().trim();
+ // Avoid useless queries for keystrokes that do not modify
+ // the text.
+ if (text.equals(selectedUser))
+ return;
+ selectedUser = text;
+ // Go to the server only if the user typed the @ character.
+ if (selectedUser.endsWith("@"))
+ updateSuggestions();
+ }
+ });
+ permTable.setWidget(1, 0, suggestBox);
+ } else
+ permTable.setWidget(1, 0, groupBox);
+ permTable.setWidget(1, 1, read);
+ permTable.setWidget(1, 2, write);
+ permTable.setWidget(1, 3, modifyACL);
+
+ permTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");
+ permTable.getFlexCellFormatter().setHorizontalAlignment(1, 1, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(1, 2, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(1, 3, HasHorizontalAlignment.ALIGN_CENTER);
+ panel.add(permTable);
+
+ final Button ok = new Button("OK", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ addPermission();
+ hide();
+ }
+ });
+ ok.getElement().setId("addPermission.button.ok");
+ buttons.add(ok);
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);
+ // Create the 'Cancel' button, along with a listener that hides the
+ // dialog
+ // when the button is clicked.
+ final Button cancel = new Button("Cancel", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
+ cancel.getElement().setId("addPermission.button.cancel");
+ buttons.add(cancel);
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
+ buttons.setSpacing(8);
+ buttons.addStyleName("gss-TabPanelBottom");
+ panel.add(buttons);
+ panel.addStyleName("gss-TabPanelBottom");
+ }
+
+ private void addPermission() {
+ PermissionHolder perm = new PermissionHolder();
+ if (userAdd) {
+ selectedUser = suggestBox.getText();
+ for(PermissionHolder p : permList.permissions)
+ if (selectedUser.equals(p.getUser())){
+ GSS.get().displayError("User already has access to the resource");
+ return;
+ }
+ perm.setUser(selectedUser);
+ } else {
+ String groupId = groupBox.getValue(groupBox.getSelectedIndex());
+ GroupResource selected = null;
+ for (GroupResource g : groups)
+ if (g.getName().equals(groupId))
+ selected = g;
+ if (selected == null)
+ return;
+ for(PermissionHolder p : permList.permissions)
+ if (selected.getName().equals(p.getGroup())){
+ GSS.get().displayError("Group already has access to the resource");
+ return;
+ }
+ perm.setGroup(selected.getName());
+ }
+ boolean readValue = read.getValue();
+ boolean writeValue = write.getValue();
+ boolean modifyValue = modifyACL.getValue();
+
+ perm.setRead(readValue);
+ perm.setWrite(writeValue);
+ perm.setModifyACL(modifyValue);
+ permList.addPermission(perm);
+ permList.updateTable();
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when either
+ // enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ addPermission();
+ hide();
+ break;
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ break;
+ }
+ }
+
+
+ @Override
+ public void center() {
+ super.center();
+ if (userAdd)
+ suggestBox.setFocus(true);
+ }
+
+ /**
+ * Update the list of suggestions.
+ */
+ protected void updateSuggestions() {
+ final GSS app = GSS.get();
+ String query = selectedUser.substring(0, selectedUser.length()-1);
+ GWT.log("Searching for " + query, null);
+
+ GetCommand<UserSearchResource> eg = new GetCommand<UserSearchResource>(UserSearchResource.class,
+ app.getApiPath() + "users/" + URL.encodeComponent(query), false, null) {
+
+ @Override
+ public void onComplete() {
+ suggestBox.hideSuggestionList();
+ oracle.clear();
+ UserSearchResource s = getResult();
+ for (UserResource user : s.getUsers()) {
+ GWT.log("Found " + user.getUsername(), null);
+ oracle.add(user.getUsername());
+ }
+ suggestBox.showSuggestionList();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ if(t instanceof RestException)
+ app.displayError("Unable to perform search: "+((RestException)t).getHttpStatusText());
+ else
+ app.displayError("System error while searching for users: "+t.getMessage());
+ GWT.log("", t);
+ DisplayHelper.log(t.getMessage());
+ }
+
+ };
+ DeferredCommand.addCommand(eg);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.FilePropertiesDialog.Images;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.resource.PermissionHolder;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import org.gss_project.gss.web.client.rest.resource.UserSearchResource;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.CheckBox;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.PushButton;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class PermissionsList extends Composite {
+
+ int selectedRow = -1;
+
+ int permissionCount = -1;
+
+ Set<PermissionHolder> permissions = null;
+
+ final Images images;
+
+ final VerticalPanel permPanel = new VerticalPanel();
+
+ final FlexTable permTable = new FlexTable();
+
+ final String owner;
+
+ PermissionHolder toRemove = null;
+
+ private boolean hasChanges = false;
+
+ private boolean hasAddition = false;
+
+ public PermissionsList(final Images theImages, Set<PermissionHolder> thePermissions, String anOwner){
+ images = theImages;
+ owner = anOwner;
+ permissions = new HashSet<PermissionHolder>();
+ permissions.addAll(thePermissions);
+ permTable.setText(0, 0, "Users/Groups");
+ permTable.setText(0, 1, "Read");
+ permTable.setText(0, 2, "Write");
+ permTable.setText(0, 3, "Modify Access");
+ permTable.setText(0, 4, "");
+ permTable.getFlexCellFormatter().setStyleName(0, 0, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 1, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 2, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 3, "props-toplabels");
+ permPanel.add(permTable);
+ permPanel.addStyleName("gss-TabPanelBottom");
+ initWidget(permPanel);
+ updateTable();
+ }
+
+ public boolean hasChanges(){
+ return hasChanges || hasAddition;
+ }
+
+
+ public void updateTable(){
+ copySetAndContinue(permissions);
+ }
+
+ public void updatePermissionsAccordingToInput(){
+ int i=1;
+ for(PermissionHolder dto : permissions){
+ /*if(dto.getId() == null)
+ hasChanges =true;*/
+ CheckBox r = (CheckBox) permTable.getWidget(i, 1);
+ CheckBox w = (CheckBox) permTable.getWidget(i, 2);
+ CheckBox m = (CheckBox) permTable.getWidget(i, 3);
+
+ r.getElement().setId("permissionList.read");
+ w.getElement().setId("permissionList.write");
+ m.getElement().setId("permissionList.modify");
+
+ if(dto.isRead() != r.getValue() || dto.isWrite() != w.getValue() || dto.isModifyACL() != m.getValue())
+ hasChanges = true;
+ dto.setRead(r.getValue());
+ dto.setWrite(w.getValue());
+ dto.setModifyACL(m.getValue());
+ i++;
+ }
+ }
+
+ /**
+ * Retrieve the permissions.
+ *
+ * @return the permissions
+ */
+ public Set<PermissionHolder> getPermissions() {
+ return permissions;
+ }
+
+ public void addPermission(PermissionHolder permission){
+ permissions.add(permission);
+ hasAddition = true;
+ }
+ /**
+ * Copies the input Set to a new Set
+ * @param input
+ */
+ private void copySetAndContinue(Set<PermissionHolder> input){
+ Set<PermissionHolder> copiedInput = new HashSet<PermissionHolder>();
+ for(PermissionHolder dto : input) {
+ copiedInput.add(dto);
+ }
+ handleFullNames(copiedInput);
+ }
+
+ /**
+ * Examines whether or not the user's full name exists in the
+ * userFullNameMap in the GSS.java for every element of the input list.
+ * If the user's full name does not exist in the map then a request is being made
+ * for the specific username.
+ *
+ * @param filesInput
+ */
+ private void handleFullNames(Set<PermissionHolder> aPermissions){
+ if(aPermissions.isEmpty()){
+ showPermissionTable();
+ return;
+ }
+
+ final PermissionHolder dto = aPermissions.iterator().next();
+ if(dto.getGroup() != null){
+ if(aPermissions.size() >= 1){
+ aPermissions.remove(dto);
+ handleFullNames(aPermissions);
+ }
+ }else if(GSS.get().findUserFullName(dto.getUser()) != null){
+ if(aPermissions.size() >= 1){
+ aPermissions.remove(dto);
+ handleFullNames(aPermissions);
+ }
+ }else{
+ findFullNameAndUpdate(aPermissions);
+ }
+ }
+
+ /**
+ * Shows the permission table
+ *
+ * @param aPermissions
+ */
+ private void showPermissionTable(){
+ int i = 1;
+ if(toRemove != null){
+ permissions.remove(toRemove);
+ toRemove = null;
+ }
+ for(final PermissionHolder dto : permissions){
+ PushButton removeButton = new PushButton(AbstractImagePrototype.create(images.delete()).createImage(), new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ toRemove = dto;
+ updateTable();
+ hasChanges = true;
+ }
+ });
+
+ if(dto.getUser() != null){
+ if(dto.getUser() != null && dto.getUser().equals(owner)){
+ permTable.setHTML(i, 0, "<span id=permissionList.Owner>" + AbstractImagePrototype.create(images.permUser()).getHTML() + " Owner</span>");
+ removeButton.setVisible(false);
+ }else{
+ permTable.setHTML(i, 0, "<span id=permissionList."+GSS.get().findUserFullName(dto.getUser())+">"+ AbstractImagePrototype.create(images.permUser()).getHTML() + " "+ GSS.get().findUserFullName(dto.getUser()) + "</span>");
+ }
+ }else if(dto.getGroup() != null){
+ permTable.setHTML(i, 0, "<span id=permissionList."+dto.getGroup()+">" + AbstractImagePrototype.create(images.permGroup()).getHTML() + " "+ dto.getGroup() + "</span>");
+ }
+
+ CheckBox read = new CheckBox();
+ read.setValue(dto.isRead());
+ read.getElement().setId("permissionList.read");
+
+ CheckBox write = new CheckBox();
+ write.setValue(dto.isWrite());
+ write.getElement().setId("permissionList.write");
+
+ CheckBox modify = new CheckBox();
+ modify.setValue(dto.isModifyACL());
+ modify.getElement().setId("permissionList.modify");
+
+ if (dto.getUser()!=null && dto.getUser().equals(owner)) {
+ read.setEnabled(false);
+ write.setEnabled(false);
+ modify.setEnabled(false);
+ }
+
+ permTable.setWidget(i, 1, read);
+ permTable.setWidget(i, 2, write);
+ permTable.setWidget(i, 3, modify);
+ permTable.setWidget(i, 4, removeButton);
+ permTable.getFlexCellFormatter().setStyleName(i, 0, "props-labels");
+ permTable.getFlexCellFormatter().setHorizontalAlignment(i, 1, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(i, 2, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(i, 3, HasHorizontalAlignment.ALIGN_CENTER);
+ i++;
+ }
+ for(; i<permTable.getRowCount(); i++)
+ permTable.removeRow(i);
+ hasChanges = false;
+ }
+
+ /**
+ * Makes a request to search for full name from a given username
+ * and continues checking the next element of the Set.
+ *
+ * @param filesInput
+ */
+
+ private void findFullNameAndUpdate(final Set<PermissionHolder> aPermissions){
+ final PermissionHolder dto = aPermissions.iterator().next();
+ String path = GSS.get().getApiPath() + "users/" + dto.getUser();
+
+ GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
+ @Override
+ public void onComplete() {
+ final UserSearchResource result = getResult();
+ for (UserResource user : result.getUsers()){
+ String username = user.getUsername();
+ String userFullName = user.getName();
+ GSS.get().putUserToMap(username, userFullName);
+ if(aPermissions.size() >= 1){
+ aPermissions.remove(dto);
+ if(aPermissions.isEmpty()){
+ showPermissionTable();
+ return;
+ }
+ handleFullNames(aPermissions);
+ }
+ }
+ }
+ @Override
+ public void onError(Throwable t) {
+ GSS.get().displayError("Unable to fetch user's full name from the given username " + dto.getUser());
+ if(aPermissions.size() >= 1){
+ aPermissions.remove(dto);
+ if(aPermissions.isEmpty()){
+ showPermissionTable();
+ return;
+ }
+ handleFullNames(aPermissions);
+ }
+ }
+ };
+ DeferredCommand.addCommand(gg);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.Grid;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+/**
+ * <P>
+ * A simple progress bar that uses table elements to show progress and with a
+ * basic time remaining calculation built in.
+ * <P>
+ * You can optionally display some text above the progress bar and/or display
+ * time remaining underneath the progress bar. To control the display of those
+ * features, set the options in the constructor as shown in the following usage
+ * example:
+ *
+ * <PRE>
+ * final ProgressBar progressBar = new ProgressBar(20, ProgressBar.SHOW_TIME_REMAINING + ProgressBar.SHOW_TEXT);
+ * progressBar.setText("Doing something...");
+ * RootPanel.get().add(progressBar);
+ * Timer t = new Timer() {
+ *
+ * public void run() {
+ * int progress = progressBar.getProgress() + 4;
+ * if (progress > 100)
+ * cancel();
+ * progressBar.setProgress(progress);
+ * }
+ * };
+ * t.scheduleRepeating(1000);
+ * </PRE>
+ * <P>
+ * How the time remaining is displayed can be controlled by setting the relevant
+ * messages using the language of your choice.
+ * <P>
+ * The default setting for the messages are as follows:
+ *
+ * <PRE>
+ * setSecondsMessage("Time remaining: {0} Seconds");
+ * setMinutesMessage("Time remaining: {0} Minutes");
+ * setHoursMessage("Time remaining: {0} Hours");
+ * </PRE>
+ * <P>
+ * To reset the time remaining/set the start time, simply set the progress to
+ * zero.
+ * <P>
+ * Some basic CSS styling is available to control the text, border around the
+ * progress bar itself and the colour of the progress bar elements.
+ *
+ * <PRE>
+ * .progressbar-text {
+ * font-weight: bold;
+ * }
+ * .progressbar-remaining {
+ * font-size: 12px;
+ * font-style: italic;
+ * }
+ * .progressbar-outer {
+ * border: 1px solid black;
+ * }
+ * .progressbar-inner {
+ * border: 1px solid black;
+ * margin: 1px;
+ * }
+ * .progressbar-bar {
+ * width: 5px;
+ * height: 15px;
+ * margin: 1px;
+ * }
+ * .progressbar-fullbar {
+ * background: blue;
+ * }
+ * .progressbar-blankbar {
+ * background: #eee;
+ * }
+ *</PRE>
+ * <P>
+ * You can take advantage of the default style by adding the following to the
+ * head of your HTML page.
+ * <P>
+ * <link rel="stylesheet" type="text/css" href="style/gwl-progressBar.css">
+ * <P>
+ * This style sheet also has two additional styles which you can use by adding
+ * the stye name to the widget. You can use either one of these, or use both
+ * combined.
+ *
+ * <PRE>
+ * ProgressBar progressBar = new ProgressBar(20);
+ * progressBar.addStyleName("progressbar-solid");
+ * progressBar.addStyleName("progressbar-noborder");
+ * </PRE>
+ *
+ * @author Bjarne Matzen - Bjarne[dot]Matzen[at]gmail[dot]com
+ */
+
+public class ProgressBar extends VerticalPanel {
+
+ /**
+ * Option to show text label above progress bar
+ */
+ public static final int SHOW_TEXT = 2;
+
+ /**
+ * Option to show time remaining
+ */
+ public static final int SHOW_TIME_REMAINING = 1;
+
+ /**
+ * The time the progress bar was started
+ */
+ private long startTime = System.currentTimeMillis();
+
+ /**
+ * The number of bar elements to show
+ */
+ private int elements = 20;
+
+ /**
+ * Time element text
+ */
+ private String secondsMessage = "Estimated time remaining: {0} Seconds";
+
+ private String minutesMessage = "Estimated time remaining: {0} Minutes";
+
+ private String hoursMessage = "Estimated time remaining: {0} Hours";
+
+ /**
+ * Current progress (as a percentage)
+ */
+ private int progress = 0;
+
+ /**
+ * This is the frame around the progress bar
+ */
+ private FlexTable barFrame = new FlexTable();
+
+ /**
+ * This is the grid used to show the elements
+ */
+ private Grid elementGrid;
+
+ /**
+ * This is the current text label below the progress bar
+ */
+ private Label remainLabel = new Label();
+
+ /**
+ * This is the current text label above the progress bar
+ */
+ private Label textLabel = new Label();
+
+ /**
+ * internal flags for options
+ */
+ private boolean showRemaining = false;
+
+ private boolean showText = false;
+
+ /**
+ * Base constructor for this widget
+ *
+ * @param elementNo The number of elements (bars) to show on the progress bar
+ * @param options The display options for the progress bar
+ */
+ public ProgressBar(int elementNo, int options) {
+ // Read the options and set convenience variables
+ if ((options & SHOW_TIME_REMAINING) == SHOW_TIME_REMAINING)
+ showRemaining = true;
+ if ((options & SHOW_TEXT) == SHOW_TEXT)
+ showText = true;
+
+ // Set element count
+ elements = elementNo;
+
+ // Styling
+ remainLabel.setStyleName("progressbar-remaining");
+ textLabel.setStyleName("progressbar-text");
+
+ // Initialize the progress elements
+ elementGrid = new Grid(1, elementNo);
+ elementGrid.setStyleName("progressbar-inner");
+ elementGrid.setCellPadding(0);
+ elementGrid.setCellSpacing(0);
+
+ for (int loop = 0; loop < elementNo; loop++) {
+ Grid elm = new Grid(1, 1);
+ // elm.setHTML(0, 0, " ");
+ elm.setHTML(0, 0, "");
+ elm.setStyleName("progressbar-blankbar");
+ elm.addStyleName("progressbar-bar");
+ elementGrid.setWidget(0, loop, elm);
+ }
+
+ // Create the container around the elements
+ Grid containerGrid = new Grid(1, 1);
+ containerGrid.setCellPadding(0);
+ containerGrid.setCellSpacing(0);
+ containerGrid.setWidget(0, 0, elementGrid);
+ containerGrid.setStyleName("progressbar-outer");
+ // containerGrid.setBorderWidth(1);
+
+ // Set up the surrounding flex table based on the options
+ int row = 0;
+ if (showText)
+ barFrame.setWidget(row++, 0, textLabel);
+ barFrame.setWidget(row++, 0, containerGrid);
+ if (showRemaining)
+ barFrame.setWidget(row++, 0, remainLabel);
+
+ barFrame.setWidth("100%");
+
+ // Add the frame to the panel
+ this.add(barFrame);
+
+ // Initialize progress bar
+ setProgress(0);
+ }
+
+ /**
+ * Constructor without options
+ *
+ * @param elementNo The number of elements (bars) to show on the progress bar
+ */
+ public ProgressBar(int elementNo) {
+ this(elementNo, 0);
+ }
+
+ /**
+ * Set the current progress as a percentage
+ *
+ * @param percentage Set current percentage for the progress bar
+ */
+ public void setProgress(int percentage) {
+ // Make sure we are error-tolerant
+ if (percentage > 100)
+ percentage = 100;
+ if (percentage < 0)
+ percentage = 0;
+
+ // Set the internal variable
+ progress = percentage;
+
+ // Update the elements in the progress grid to
+ // reflect the status
+ int completed = elements * percentage / 100;
+ for (int loop = 0; loop < elements; loop++) {
+ Grid elm = (Grid) elementGrid.getWidget(0, loop);
+ if (loop < completed) {
+ elm.setStyleName("progressbar-fullbar");
+ elm.addStyleName("progressbar-bar");
+ } else {
+ elm.setStyleName("progressbar-blankbar");
+ elm.addStyleName("progressbar-bar");
+ }
+ }
+
+ if (percentage > 0) {
+ // Calculate the new time remaining
+ long soFar = (System.currentTimeMillis() - startTime) / 1000;
+ long remaining = soFar * (100 - percentage) / percentage;
+ // Select the best UOM
+ String remainText = secondsMessage;
+ if (remaining > 120) {
+ remaining = remaining / 60;
+ remainText = minutesMessage;
+ if (remaining > 120) {
+ remaining = remaining / 60;
+ remainText = hoursMessage;
+ }
+ }
+ // Locate the position to insert out time remaining
+ int pos = remainText.indexOf("{0}");
+ if (pos >= 0) {
+ String trail = "";
+ if (pos + 3 < remainText.length())
+ trail = remainText.substring(pos + 3);
+ remainText = remainText.substring(0, pos) + remaining + trail;
+ }
+ // Set the label
+ remainLabel.setText(remainText);
+ } else
+ // If progress is 0, reset the start time
+ startTime = System.currentTimeMillis();
+ }
+
+ /**
+ * Get the current progress as a percentage
+ *
+ * @return Current percentage for the progress bar
+ */
+ public int getProgress() {
+ return progress;
+ }
+
+ /**
+ * Get the text displayed above the progress bar
+ *
+ * @return the text
+ */
+ public String getText() {
+ return textLabel.getText();
+ }
+
+ /**
+ * Set the text displayed above the progress bar
+ *
+ * @param text the text to set
+ */
+ public void setText(String text) {
+ textLabel.setText(text);
+ }
+
+ /**
+ * Get the message used to format the time remaining text for hours
+ *
+ * @return the hours message
+ */
+ public String getHoursMessage() {
+ return hoursMessage;
+ }
+
+ /**
+ * Set the message used to format the time remaining text below the progress
+ * bar. There are 3 messages used for hours, minutes and seconds
+ * respectively. The message must contain a placeholder for the value. The
+ * placeholder must be {0}. For example, the following is a valid message:
+ * "Hours remaining: {0}"
+ *
+ * @param anHoursMessage the hours message to set
+ */
+ public void setHoursMessage(String anHoursMessage) {
+ hoursMessage = anHoursMessage;
+ }
+
+ /**
+ * Get the message used to format the time remaining text for minutes
+ *
+ * @return the minutesMessage
+ */
+ public String getMinutesMessage() {
+ return minutesMessage;
+ }
+
+ /**
+ * Set the message used to format the time remaining text below the progress
+ * bar. There are 3 messages used for hours, minutes and seconds
+ * respectively. The message must contain a placeholder for the value. The
+ * placeholder must be {0}. For example, the following is a valid message:
+ * "Minutes remaining: {0}"
+ *
+ * @param aMinutesMessage the minutes message to set
+ */
+ public void setMinutesMessage(String aMinutesMessage) {
+ minutesMessage = aMinutesMessage;
+ }
+
+ /**
+ * Get the message used to format the time remaining text for seconds
+ *
+ * @return the secondsMessage
+ */
+ public String getSecondsMessage() {
+ return secondsMessage;
+ }
+
+ /**
+ * Set the message used to format the time remaining text below the progress
+ * bar. There are 3 messages used for hours, minutes and seconds
+ * respectively. The message must contain a placeholder for the value. The
+ * placeholder must be {0}. For example, the following is a valid message:
+ * "Seconds remaining: {0}"
+ *
+ * @param aSecondsMessage the secondsMessage to set
+ */
+ public void setSecondsMessage(String aSecondsMessage) {
+ secondsMessage = aSecondsMessage;
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.dom.client.NativeEvent;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.user.client.Event.NativePreviewEvent;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.DialogBox;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.VerticalPanel;\r
+\r
+/**\r
+ * The 'quit' dialog box.\r
+ */\r
+public class QuitDialog extends DialogBox {\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ */\r
+ public QuitDialog() {\r
+ Configuration conf = (Configuration) GWT.create(Configuration.class);\r
+ String service = conf.serviceName();\r
+ setText("Quit " + service);\r
+\r
+ VerticalPanel outer = new VerticalPanel();\r
+ HorizontalPanel buttons = new HorizontalPanel();\r
+\r
+ HTML text = new HTML("Are you sure you want to quit " + service + "?");\r
+ text.setStyleName("gss-AboutText");\r
+ outer.add(text);\r
+\r
+ // Create the 'Quit' button, along with a listener that hides the dialog\r
+ // when the button is clicked and quits the application.\r
+ Button quit = new Button("Quit", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ hide();\r
+ GSS.get().logout();\r
+ }\r
+ });\r
+ buttons.add(quit);\r
+ buttons.setCellHorizontalAlignment(quit, HasHorizontalAlignment.ALIGN_CENTER);\r
+ // Create the 'Cancel' button, along with a listener that hides the\r
+ // dialog when the button is clicked.\r
+ Button cancel = new Button("Cancel", new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ hide();\r
+ }\r
+ });\r
+ buttons.add(cancel);\r
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
+ buttons.setSpacing(8);\r
+ outer.add(buttons);\r
+ outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
+ setWidget(outer);\r
+ }\r
+\r
+ @Override\r
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
+ super.onPreviewNativeEvent(preview);\r
+\r
+ NativeEvent evt = preview.getNativeEvent();\r
+ if (evt.getType().equals("keydown"))\r
+ // Use the popup's key preview hooks to close the dialog when either\r
+ // enter or escape is pressed.\r
+ switch (evt.getKeyCode()) {\r
+ case KeyCodes.KEY_ENTER:\r
+ hide();\r
+ GSS.get().logout();\r
+ break;\r
+ case KeyCodes.KEY_ESCAPE:\r
+ hide();\r
+ break;\r
+ }\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import com.google.gwt.event.dom.client.BlurEvent;\r
+import com.google.gwt.event.dom.client.BlurHandler;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.FocusEvent;\r
+import com.google.gwt.event.dom.client.FocusHandler;\r
+import com.google.gwt.event.dom.client.KeyPressEvent;\r
+import com.google.gwt.event.dom.client.KeyPressHandler;\r
+import com.google.gwt.resources.client.ClientBundle;\r
+import com.google.gwt.resources.client.ImageResource;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.Composite;\r
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
+import com.google.gwt.user.client.ui.HasVerticalAlignment;\r
+import com.google.gwt.user.client.ui.HorizontalPanel;\r
+import com.google.gwt.user.client.ui.TextBox;\r
+import com.google.gwt.user.client.ui.Widget;\r
+\r
+/**\r
+ * A component that contains the search form.\r
+ */\r
+public class Search extends Composite implements FocusHandler,BlurHandler {\r
+\r
+ /**\r
+ * The text hint that is displayed in the empty search box.\r
+ */\r
+ private static final String TEXT_HINT = "Search for files...";\r
+\r
+ /**\r
+ * Specifies the images that will be bundled for this Composite.\r
+ */\r
+ public interface Images extends ClientBundle {\r
+ @Source("org/gss_project/gss/resources/search_16.png")\r
+ ImageResource searchButton();\r
+ }\r
+\r
+ /**\r
+ * The embedded text box widget that contains the search query.\r
+ */\r
+ private TextBox tb = new TextBox();\r
+\r
+ /**\r
+ * The search widget constructor.\r
+ *\r
+ * @param images the image bundle\r
+ */\r
+ public Search(final Images images) {\r
+ tb.setWidth("200px");\r
+ tb.setText(TEXT_HINT);\r
+ tb.setStylePrimaryName("gss-search");\r
+ tb.addStyleDependentName("empty");\r
+ tb.addFocusHandler(this);\r
+ tb.addBlurHandler(this);\r
+ tb.getElement().setId("textBox.search");\r
+ tb.addKeyPressHandler(new KeyPressHandler() {\r
+\r
+ @Override\r
+ public void onKeyPress(KeyPressEvent event) {\r
+ char keyCode = event.getCharCode();\r
+ if (keyCode == '\r')\r
+ GSS.get().showSearchResults(tb.getText());\r
+ else if (keyCode == 27) {\r
+ // Simulate the proper behavior for the escape key\r
+ // (27 == ESC).\r
+ onLostFocus((Widget)event.getSource());\r
+ tb.setFocus(false);\r
+ }\r
+ }\r
+ });\r
+\r
+ Button b = new Button(createHeaderHTML(images.searchButton(), "Search"), new ClickHandler() {\r
+ @Override\r
+ public void onClick(ClickEvent event) {\r
+ GSS.get().showSearchResults(tb.getText());\r
+ }\r
+ });\r
+ b.getElement().setId("button.search");\r
+ \r
+ HorizontalPanel panel = new HorizontalPanel();\r
+ panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);\r
+ panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);\r
+ panel.add(tb);\r
+ panel.add(b);\r
+ initWidget(panel);\r
+ }\r
+\r
+ /**\r
+ * Creates an HTML fragment that places an image & caption together.\r
+ *\r
+ * @param imageProto an image prototype for an image\r
+ * @param caption the caption\r
+ * @return the HTML fragment\r
+ */\r
+ private String createHeaderHTML(ImageResource imageProto, String caption) {\r
+ String captionHTML = "<table cellpadding='0' cellspacing='0'>" + "<tr><td>" +\r
+ AbstractImagePrototype.create(imageProto).getHTML() + "</td><td style='font-size: 90%;'> " +\r
+ caption + "</td></tr></table>";\r
+ return captionHTML;\r
+ }\r
+\r
+ public void onLostFocus(Widget sender) {\r
+ TextBox b = (TextBox) sender;\r
+ if (b.getText().equals("")) {\r
+ b.addStyleDependentName("empty");\r
+ b.setText(TEXT_HINT);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void onFocus(FocusEvent event) {\r
+ TextBox b = (TextBox) event.getSource();\r
+ if (b.getText().equals(TEXT_HINT))\r
+ b.setText("");\r
+ b.removeStyleDependentName("empty");\r
+ }\r
+\r
+ @Override\r
+ public void onBlur(BlurEvent event) {\r
+ TextBox b = (TextBox) event.getSource();\r
+ onLostFocus(b);\r
+ }\r
+}\r
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+
+import static com.google.gwt.query.client.GQuery.$;
+
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.RestCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.SearchResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import org.gss_project.gss.web.client.rest.resource.UserSearchResource;
+import gwtquery.plugins.draggable.client.DraggableOptions;
+import gwtquery.plugins.draggable.client.StopDragException;
+import gwtquery.plugins.draggable.client.DraggableOptions.DragFunction;
+import gwtquery.plugins.draggable.client.DraggableOptions.RevertOption;
+import gwtquery.plugins.draggable.client.events.DragContext;
+import gwtquery.plugins.draggable.client.events.DragStartEvent;
+import gwtquery.plugins.draggable.client.events.DragStopEvent;
+import gwtquery.plugins.draggable.client.events.DragStartEvent.DragStartEventHandler;
+import gwtquery.plugins.draggable.client.events.DragStopEvent.DragStopEventHandler;
+import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTable;
+import gwtquery.plugins.droppable.client.gwt.DragAndDropColumn;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import com.google.gwt.cell.client.AbstractCell;
+import com.google.gwt.cell.client.ImageResourceCell;
+import com.google.gwt.cell.client.SafeHtmlCell;
+import com.google.gwt.cell.client.TextCell;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.RepeatingCommand;
+import com.google.gwt.dom.client.Style.Cursor;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.user.cellview.client.CellTable;
+import com.google.gwt.user.cellview.client.GssSimplePager;
+import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.view.client.AsyncDataProvider;
+import com.google.gwt.view.client.HasData;
+import com.google.gwt.view.client.MultiSelectionModel;
+import com.google.gwt.view.client.ProvidesKey;
+import com.google.gwt.view.client.SelectionChangeEvent;
+import com.google.gwt.view.client.SelectionChangeEvent.Handler;
+
+/**
+ * A composite that displays a list of search results for a particular query on
+ * files.
+ */
+public class SearchResults extends Composite{
+ private HTML searchResults = new HTML("Results for search:");
+ private String lastQuery;
+ SearchDataProvider provider = new SearchDataProvider();
+ /**
+ * Specifies that the images available for this composite will be the ones
+ * available in FileContextMenu.
+ */
+ public interface Images extends ClientBundle,FileContextMenu.Images, CellTreeView.Images, FileList.Images {
+
+ @Source("org/gss_project/gss/resources/blank.gif")
+ ImageResource blank();
+
+ @Source("org/gss_project/gss/resources/asc.png")
+ ImageResource asc();
+
+ @Source("org/gss_project/gss/resources/desc.png")
+ ImageResource desc();
+ }
+
+
+ interface TableResources extends DragAndDropCellTable.Resources {
+ @Source({CellTable.Style.DEFAULT_CSS, "GssCellTable.css"})
+ TableStyle cellTableStyle();
+ }
+
+ /**
+ * The styles applied to the table.
+ */
+ interface TableStyle extends CellTable.Style {
+ }
+
+ private String showingStats = "";
+
+ private int startIndex = 0;
+
+ /**
+ * A constant that denotes the completion of an IncrementalCommand.
+ */
+ public static final boolean DONE = false;
+
+
+
+ private final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
+
+
+
+ DragStopEventHandler dragStop = new DragStopEventHandler() {
+
+ @Override
+ public void onDragStop(DragStopEvent event) {
+ GWT.log("DRAG STOPPED");
+
+ }
+ };
+
+ private static class ContactCell extends AbstractCell<org.gss_project.gss.web.client.rest.resource.FileResource> {
+
+ /**
+ * The html of the image used for contacts.
+ *
+ */
+ private final String imageHtml;
+
+ public ContactCell(ImageResource image) {
+ this.imageHtml = AbstractImagePrototype.create(image).getHTML();
+ }
+
+
+
+
+
+ @Override
+ public void render(Context context, FileResource value, SafeHtmlBuilder sb) {
+ // Value can be null, so do a null check..
+ if (value == null) {
+ return;
+ }
+
+ sb.append(FileList.Templates.INSTANCE.rendelContactCell(imageHtml, value.getName(), value.getFileSizeAsString()));
+ }
+
+
+ }
+ /**
+ * Retrieve the celltable.
+ *
+ * @return the celltable
+ */
+ public DragAndDropCellTable<FileResource> getCelltable() {
+ return celltable;
+ }
+
+
+
+ /**
+ * The number of files in this folder.
+ */
+ int folderFileCount;
+
+ /**
+ * Total folder size
+ */
+ long folderTotalSize;
+
+ /**
+ * A cache of the files in the list.
+ */
+ private List<FileResource> files;
+
+ /**
+ * The widget's image bundle.
+ */
+ private final Images images;
+
+ private FileContextMenu menuShowing;
+ private DragAndDropCellTable<FileResource> celltable;
+ private final MultiSelectionModel<FileResource> selectionModel;
+
+ GssSimplePager pager;
+ GssSimplePager pagerTop;
+ /**
+ * Construct the file list widget. This entails setting up the widget
+ * layout, fetching the number of files in the current folder from the
+ * server and filling the local file cache of displayed files with data from
+ * the server, as well.
+ *
+ * @param _images
+ */
+ public SearchResults(Images _images) {
+ images = _images;
+ DragAndDropCellTable.Resources resources = GWT.create(TableResources.class);
+ ProvidesKey<FileResource> keyProvider = new ProvidesKey<FileResource>(){
+
+ @Override
+ public Object getKey(FileResource item) {
+ return item.getUri();
+ }
+
+ };
+
+ celltable = new DragAndDropCellTable<FileResource>(GSS.VISIBLE_FILE_COUNT,resources,keyProvider){
+ @Override
+ protected void onBrowserEvent2(Event event) {
+ /*if (DOM.eventGetType((Event) event) == Event.ONMOUSEDOWN && DOM.eventGetButton((Event) event) == NativeEvent.BUTTON_RIGHT){
+ fireClickEvent((Element) event.getEventTarget().cast());
+ }*/
+ super.onBrowserEvent2(event);
+ }
+ };
+ provider.addDataDisplay(celltable);
+ celltable.addDragStopHandler(dragStop);
+ celltable.addDragStartHandler(new DragStartEventHandler() {
+
+ public void onDragStart(DragStartEvent event) {
+ FileResource value = event.getDraggableData();
+
+ com.google.gwt.dom.client.Element helper = event.getHelper();
+ SafeHtmlBuilder sb = new SafeHtmlBuilder();
+ sb.appendHtmlConstant("<b>");
+ DisplayHelper.log(value.getName());
+ if(getSelectedFiles().size()==1)
+ sb.appendEscaped(value.getName());
+ else
+ sb.appendEscaped(getSelectedFiles().size()+" files");
+ sb.appendHtmlConstant("</b>");
+ helper.setInnerHTML(sb.toSafeHtml().asString());
+
+ }
+ });
+ DragAndDropColumn<FileResource, ImageResource> status = new DragAndDropColumn<FileResource, ImageResource>(new ImageResourceCell(){
+ @Override
+ public boolean handlesSelection() {
+ return false;
+ }
+ }) {
+ @Override
+ public ImageResource getValue(FileResource entity) {
+ return getFileIcon(entity);
+ }
+
+ };
+ celltable.addColumn(status,"");
+
+ initDragOperation(status);
+ final DragAndDropColumn<FileResource,SafeHtml> nameColumn = new DragAndDropColumn<FileResource,SafeHtml>(new SafeHtmlCell()) {
+
+
+ @Override
+ public SafeHtml getValue(FileResource object) {
+ SafeHtmlBuilder sb = new SafeHtmlBuilder();
+ sb.append(FileList.Templates.INSTANCE.filenameSpan(object.getName()));
+ if (object.getContentType().endsWith("png") || object.getContentType().endsWith("gif") || object.getContentType().endsWith("jpeg") ){
+ sb.appendHtmlConstant(" ").append(FileList.Templates.INSTANCE.viewLink(GSS.get().getTopPanel().getFileMenu().getDownloadURL(object), object.getOwner() + " : " + object.getPath() + object.getName()));
+ }
+
+ return sb.toSafeHtml();
+ }
+
+ };
+ initDragOperation(nameColumn);
+ celltable.addColumn(nameColumn,"Name");
+
+ DragAndDropColumn<FileResource,String> aColumn;
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ return GSS.get().findUserFullName(object.getOwner());
+ }
+ },"Owner");
+ initDragOperation(aColumn);
+
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ if(object.isDeleted())
+ return object.getPath()+" (In Trash)";
+ return object.getPath();
+ }
+ },"Path");
+ initDragOperation(aColumn);
+
+
+
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ return object.getVersion().toString();
+ }
+ },"Version");
+ initDragOperation(aColumn);
+
+
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ // TODO Auto-generated method stub
+ return object.getFileSizeAsString();
+ }
+ },"Size");
+ initDragOperation(aColumn);
+
+ celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
+ @Override
+ public String getValue(FileResource object) {
+ return formatter.format(object.getModificationDate());
+ }
+ },"Last Modified");
+
+
+
+
+ VerticalPanel vp = new VerticalPanel();
+ vp.setWidth("100%");
+ celltable.setWidth("100%");
+ vp.add(searchResults);
+ searchResults.addStyleName("gss-searchLabel");
+ pagerTop = new GssSimplePager(GssSimplePager.TextLocation.CENTER);
+ pagerTop.setDisplay(celltable);
+ vp.add(pagerTop);
+ vp.add(celltable);
+ pager = new GssSimplePager(GssSimplePager.TextLocation.CENTER);
+ pager.setDisplay(celltable);
+ //celltable.setPageSize(2);
+
+ vp.add(pager);
+ vp.setCellWidth(celltable, "100%");
+
+ initWidget(vp);
+
+ //initWidget(celltable);
+ celltable.setStyleName("gss-List");
+ selectionModel = new MultiSelectionModel<FileResource>();
+
+
+ Handler selectionHandler = new SelectionChangeEvent.Handler() {
+ @Override
+ public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
+ if(getSelectedFiles().size()==1)
+ GSS.get().setCurrentSelection(getSelectedFiles().get(0));
+ else
+ GSS.get().setCurrentSelection(getSelectedFiles());
+ //contextMenu.setFiles(getSelectedFiles());
+ }
+ };
+ selectionModel.addSelectionChangeHandler(selectionHandler);
+
+ celltable.setSelectionModel(selectionModel,GSSSelectionEventManager.<FileResource>createDefaultManager());
+ celltable.setPageSize(GSS.VISIBLE_FILE_COUNT);
+ celltable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
+ Scheduler.get().scheduleIncremental(new RepeatingCommand() {
+
+ @Override
+ public boolean execute() {
+ return fetchRootFolder();
+ }
+ });
+ sinkEvents(Event.ONCONTEXTMENU);
+ sinkEvents(Event.ONMOUSEUP);
+ sinkEvents(Event.ONMOUSEDOWN);
+ sinkEvents(Event.ONCLICK);
+ sinkEvents(Event.ONKEYDOWN);
+ sinkEvents(Event.ONDBLCLICK);
+ GSS.preventIESelection();
+ }
+
+ //public native void fireClickEvent(Element element) /*-{
+ // var evObj = $doc.createEvent('MouseEvents');
+ //evObj.initEvent('click', true, true);
+ //element.dispatchEvent(evObj);
+ //}-*/;
+
+ public List<FileResource> getSelectedFiles() {
+ return new ArrayList<FileResource>(selectionModel.getSelectedSet());
+ }
+
+ private void initDragOperation(DragAndDropColumn<?, ?> column) {
+
+ // retrieve draggableOptions on the column
+ DraggableOptions draggableOptions = column.getDraggableOptions();
+ // use template to construct the helper. The content of the div will be set
+ // after
+ draggableOptions.setHelper($(FileList.Templates.INSTANCE.outerHelper().asString()));
+ //draggableOptions.setZIndex(100);
+ // opacity of the helper
+ draggableOptions.setAppendTo("body");
+ //draggableOptions.setOpacity((float) 0.8);
+ draggableOptions.setContainment("document");
+ // cursor to use during the drag operation
+ draggableOptions.setCursor(Cursor.MOVE);
+ // set the revert option
+ draggableOptions.setRevert(RevertOption.ON_INVALID_DROP);
+ // prevents dragging when user click on the category drop-down list
+ draggableOptions.setCancel("select");
+
+ draggableOptions.setOnBeforeDragStart(new DragFunction() {
+
+ @Override
+ public void f(DragContext context) {
+ FileResource value = context.getDraggableData();
+ if(!selectionModel.isSelected(value)){
+ throw new StopDragException();
+ }
+
+ }
+ });
+ }
+
+ public void showContextMenu(Event event){
+ menuShowing = new FileContextMenu(images, false, true);
+ menuShowing=menuShowing.onEmptyEvent(event);
+ }
+ @Override
+ public void onBrowserEvent(Event event) {
+
+ if (files == null || files.size() == 0) {
+ if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
+ menuShowing = new FileContextMenu(images, false, true);
+ menuShowing=menuShowing.onEmptyEvent(event);
+ event.preventDefault();
+ event.cancelBubble(true);
+ }
+ return;
+ }
+ if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() != 0) {
+ GWT.log("*****GOING TO SHOW CONTEXT MENU ****", null);
+ menuShowing = new FileContextMenu(images, false, false);
+ menuShowing=menuShowing.onEvent(event);
+ event.cancelBubble(true);
+ event.preventDefault();
+ } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
+ menuShowing = new FileContextMenu(images, false, true);
+ menuShowing=menuShowing.onEmptyEvent(event);
+ event.cancelBubble(true);
+ event.preventDefault();
+ } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
+ if (getSelectedFiles().size() == 1) {
+ GSS app = GSS.get();
+ FileResource file = getSelectedFiles().get(0);
+ String dateString = RestCommand.getDate();
+ String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
+ String sig = app.getCurrentUserResource().getUsername() + " " +
+ RestCommand.calculateSig("GET", dateString, resource,
+ RestCommand.base64decode(app.getToken()));
+ if(!file.isDeleted()){
+ Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
+ }
+ event.preventDefault();
+ return;
+ }
+ super.onBrowserEvent(event);
+ }
+
+ /**
+ * Retrieve the root folder for the current user.
+ *
+ * @return true if the retrieval was successful
+ */
+ protected boolean fetchRootFolder() {
+ UserResource user = GSS.get().getCurrentUserResource();
+ if (user == null)
+ return !DONE;
+ // Update cache and clear selection.
+ updateFileCache(null);
+ return DONE;
+ }
+
+
+ /**
+ * Update the display of the file list.
+ */
+ void update(boolean sort) {
+ int count = folderFileCount;
+ int max = startIndex + GSS.VISIBLE_FILE_COUNT;
+ if (max > count)
+ max = count;
+ folderTotalSize = 0;
+
+ copyListAndContinue(files);
+ for(FileResource f : files){
+ folderTotalSize += f.getContentLength();
+ }
+ if (folderFileCount == 0) {
+ showingStats = "no files";
+ } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
+ if (folderFileCount == 1)
+ showingStats = "1 file";
+ else
+ showingStats = folderFileCount + " files";
+ showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
+ } else {
+ showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
+ }
+ updateCurrentlyShowingStats();
+
+ }
+
+ /**
+ * Return the proper icon based on the MIME type of the file.
+ *
+ * @param file
+ * @return the icon
+ */
+ private ImageResource getFileIcon(FileResource file) {
+ String mimetype = file.getContentType();
+ boolean shared = file.isShared();
+ if (mimetype == null)
+ return shared ? images.documentShared() : images.document();
+ mimetype = mimetype.toLowerCase();
+ if (mimetype.startsWith("application/pdf"))
+ return shared ? images.pdfShared() : images.pdf();
+ else if (mimetype.endsWith("excel"))
+ return shared ? images.spreadsheetShared() : images.spreadsheet();
+ else if (mimetype.endsWith("msword"))
+ return shared ? images.wordprocessorShared() : images.wordprocessor();
+ else if (mimetype.endsWith("powerpoint"))
+ return shared ? images.presentationShared() : images.presentation();
+ else if (mimetype.startsWith("application/zip") ||
+ mimetype.startsWith("application/gzip") ||
+ mimetype.startsWith("application/x-gzip") ||
+ mimetype.startsWith("application/x-tar") ||
+ mimetype.startsWith("application/x-gtar"))
+ return shared ? images.zipShared() : images.zip();
+ else if (mimetype.startsWith("text/html"))
+ return shared ? images.htmlShared() : images.html();
+ else if (mimetype.startsWith("text/plain"))
+ return shared ? images.txtShared() : images.txt();
+ else if (mimetype.startsWith("image/"))
+ return shared ? images.imageShared() : images.image();
+ else if (mimetype.startsWith("video/"))
+ return shared ? images.videoShared() : images.video();
+ else if (mimetype.startsWith("audio/"))
+ return shared ? images.audioShared() : images.audio();
+ return shared ? images.documentShared() : images.document();
+ }
+
+ /**
+ * Update status panel with currently showing file stats.
+ */
+ public void updateCurrentlyShowingStats() {
+ GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
+ }
+
+ public void updateFileCache(String query) {
+ final GSS app = GSS.get();
+ setLastQuery(query);
+ clearSelectedRows();
+ //clearLabels();
+ startIndex = 0;
+ app.showLoadingIndicator("Getting Search Results",null);
+ if (query == null || query.trim().equals("")) {
+ searchResults.setHTML("You must specify a query.");
+ setFiles(new ArrayList());
+ update(true);
+ app.hideLoadingIndicator();
+ } else if (!GSS.isValidResourceName(query)) {
+ searchResults.setHTML("The query was invalid. Try to use words that appear in the file's name, contents or tags.");
+ setFiles(new ArrayList());
+ update(true);
+ app.hideLoadingIndicator();
+ } else{
+ searchResults.setHTML("Search results for " + query);
+ showCellTable(true);
+
+ }
+ }
+
+ /**
+ * Fill the file cache with data.
+ */
+ public void setFiles(final List<FileResource> _files) {
+ if (_files.size() > 0 && ! (GSS.get().getTreeView().getSelection() instanceof TrashResource)) {
+ files = new ArrayList<FileResource>();
+ for (FileResource fres : _files)
+ files.add(fres);
+ }
+ else
+ files = _files;
+ Collections.sort(files, new Comparator<FileResource>() {
+
+ @Override
+ public int compare(FileResource arg0, FileResource arg1) {
+ return arg0.getName().compareTo(arg1.getName());
+ }
+
+ });
+ folderFileCount = files.size();
+ }
+
+
+
+
+ /**
+ * Does the list contains the requested filename
+ *
+ * @param fileName
+ * @return true/false
+ */
+ public boolean contains(String fileName) {
+ for (int i = 0; i < files.size(); i++)
+ if (files.get(i).getName().equals(fileName))
+ return true;
+ return false;
+ }
+
+ public void clearSelectedRows() {
+ Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
+ while(it.hasNext()){
+ selectionModel.setSelected(it.next(),false);
+ }
+ }
+
+ /**
+ *
+ */
+ public void selectAllRows() {
+ Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
+ while(it.hasNext()){
+ selectionModel.setSelected(it.next(),true);
+ }
+
+
+ }
+
+
+ private void sortFiles(final String sortingProperty, final boolean sortingType){
+ Collections.sort(files, new Comparator<FileResource>() {
+
+ @Override
+ public int compare(FileResource arg0, FileResource arg1) {
+ AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
+ AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
+ if (sortingType){
+ if (sortingProperty.equals("version")) {
+ return arg0.getVersion().compareTo(arg1.getVersion());
+ } else if (sortingProperty.equals("owner")) {
+ return arg0.getOwner().compareTo(arg1.getOwner());
+ } else if (sortingProperty.equals("date")) {
+ return arg0.getModificationDate().compareTo(arg1.getModificationDate());
+ } else if (sortingProperty.equals("size")) {
+ return arg0.getContentLength().compareTo(arg1.getContentLength());
+ } else if (sortingProperty.equals("name")) {
+ return arg0.getName().compareTo(arg1.getName());
+ } else if (sortingProperty.equals("path")) {
+ return arg0.getUri().compareTo(arg1.getUri());
+ } else {
+ return arg0.getName().compareTo(arg1.getName());
+ }
+ }
+ else if (sortingProperty.equals("version")) {
+
+ return arg1.getVersion().compareTo(arg0.getVersion());
+ } else if (sortingProperty.equals("owner")) {
+
+ return arg1.getOwner().compareTo(arg0.getOwner());
+ } else if (sortingProperty.equals("date")) {
+
+ return arg1.getModificationDate().compareTo(arg0.getModificationDate());
+ } else if (sortingProperty.equals("size")) {
+
+ return arg1.getContentLength().compareTo(arg0.getContentLength());
+ } else if (sortingProperty.equals("name")) {
+
+ return arg1.getName().compareTo(arg0.getName());
+ } else if (sortingProperty.equals("path")) {
+
+ return arg1.getUri().compareTo(arg0.getUri());
+ } else {
+
+ return arg1.getName().compareTo(arg0.getName());
+ }
+ }
+
+ });
+ }
+
+
+ /**
+ * Creates a new ArrayList<FileResources> from the given files ArrayList
+ * in order that the input files remain untouched
+ * and continues to find user's full names of each FileResource element
+ * in the new ArrayList
+ *
+ * @param filesInput
+ */
+ private void copyListAndContinue(List<FileResource> filesInput){
+ List<FileResource> copiedFiles = new ArrayList<FileResource>();
+ for(FileResource file : filesInput) {
+ copiedFiles.add(file);
+ }
+ handleFullNames(copiedFiles);
+ }
+
+ /**
+ * Examines whether or not the user's full name exists in the
+ * userFullNameMap in the GSS.java for every element of the input list.
+ * If the user's full name does not exist in the map then a command is being made.
+ *
+ * @param filesInput
+ */
+ private void handleFullNames(List<FileResource> filesInput){
+ if(filesInput.size() == 0){
+ showCellTable(false);
+ return;
+ }
+
+ if(GSS.get().findUserFullName(filesInput.get(0).getOwner()) == null){
+ findFullNameAndUpdate(filesInput);
+ return;
+ }
+
+ if(filesInput.size() >= 1){
+ filesInput.remove(filesInput.get(0));
+ if(filesInput.isEmpty()){
+ showCellTable(false);
+ }else{
+ handleFullNames(filesInput);
+ }
+ }
+ }
+
+ /**
+ * Makes a command to search for full name from a given username.
+ * Only after the completion of the command the celltable is shown
+ * or the search for the next full name continues.
+ *
+ * @param filesInput
+ */
+ private void findFullNameAndUpdate(final List<FileResource> filesInput){
+ String aUserName = filesInput.get(0).getOwner();
+ String path = GSS.get().getApiPath() + "users/" + aUserName;
+
+ GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
+ @Override
+ public void onComplete() {
+ final UserSearchResource result = getResult();
+ for (UserResource user : result.getUsers()){
+ String username = user.getUsername();
+ String userFullName = user.getName();
+ GSS.get().putUserToMap(username, userFullName);
+ if(filesInput.size() >= 1){
+ filesInput.remove(filesInput.get(0));
+ if(filesInput.isEmpty()){
+ showCellTable(false);
+ }else{
+ handleFullNames(filesInput);
+ }
+ }
+ }
+ }
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch user's full name from the given username " + filesInput.get(0).getOwner());
+ if(filesInput.size() >= 1){
+ filesInput.remove(filesInput.get(0));
+ handleFullNames(filesInput);
+ }
+ }
+ };
+ DeferredCommand.addCommand(gg);
+
+ }
+ /**
+ * Shows the files in the cellTable
+ */
+
+ private void showCellTable(boolean update){
+ if(celltable.getRowCount()>GSS.VISIBLE_FILE_COUNT){
+ pager.setVisible(true);
+ pagerTop.setVisible(true);
+ }
+ else{
+ pager.setVisible(false);
+ pagerTop.setVisible(false);
+ }
+ if(update)
+ provider.onRangeChanged(celltable);
+ celltable.redrawHeaders();
+ }
+
+
+ /**
+ * Retrieve the lastQuery.
+ *
+ * @return the lastQuery
+ */
+ public String getLastQuery() {
+ return lastQuery;
+ }
+
+
+ /**
+ * Modify the lastQuery.
+ *
+ * @param lastQuery the lastQuery to set
+ */
+ public void setLastQuery(String lastQuery) {
+ this.lastQuery = lastQuery;
+ }
+
+ class SearchDataProvider extends AsyncDataProvider<FileResource>{
+
+ @Override
+ protected void onRangeChanged(final HasData<FileResource> display) {
+ final int start = display.getVisibleRange().getStart();
+ final GSS app = GSS.get();
+ if(getLastQuery()==null||getLastQuery().equals("")){
+ display.setRowCount(0,true);
+ return;
+
+ }
+ GetCommand<SearchResource> eg = new GetCommand<SearchResource>(SearchResource.class,
+ app.getApiPath() + "search/" +URL.encodeComponent(getLastQuery())+"?start="+start, null) {
+
+ @Override
+ public void onComplete() {
+ SearchResource s = getResult();
+ display.setRowCount(s.getSize(),true);
+ display.setRowData(start, s.getFiles());
+ setFiles(s.getFiles());
+ update(true);
+
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ if(t instanceof RestException)
+ app.displayError("Unable to perform search:"+((RestException)t).getHttpStatusText());
+ else
+ app.displayError("System error performing search:"+t.getMessage());
+ GWT.log("",t);
+ updateFileCache("");
+ }
+
+ };
+ DeferredCommand.addCommand(eg);
+
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class SessionExpiredDialog extends DialogBox {
+ /**
+ * The widget constructor.
+ */
+ public SessionExpiredDialog() {
+ // Set the dialog's caption.
+ setText("Session Expired");
+ setAnimationEnabled(true);
+ VerticalPanel outer = new VerticalPanel();
+
+ // Create the text and set a style name so we can style it with CSS.
+ HTML text = new HTML("<p>Your session has expired. You will have to reauthenticate with your Identity Provider.</p> ");
+ text.setStyleName("gss-AboutText");
+ outer.add(text);
+
+ // Create the 'OK' button, along with a listener that hides the dialog
+ // when the button is clicked.
+ Button confirm = new Button("Proceed", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ GSS.get().authenticateUser();
+ hide();
+ }
+ });
+ outer.add(confirm);
+ outer.setCellHorizontalAlignment(confirm, HasHorizontalAlignment.ALIGN_CENTER);
+ outer.setSpacing(8);
+ setWidget(outer);
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when either
+ // enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ GSS.get().authenticateUser();
+ hide();
+ break;
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ break;
+ }
+ }
+
+
+
+}
--- /dev/null
+/*\r
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
+ *\r
+ * This file is part of GSS.\r
+ *\r
+ * GSS is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 3 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * GSS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package org.gss_project.gss.web.client;\r
+\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.resources.client.ClientBundle;\r
+import com.google.gwt.resources.client.ImageResource;\r
+import com.google.gwt.user.client.Command;\r
+import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
+import com.google.gwt.user.client.ui.MenuBar;\r
+import com.google.gwt.user.client.ui.MenuItem;\r
+import com.google.gwt.user.client.ui.PopupPanel;\r
+\r
+/**\r
+ * The 'settings' menu implementation.\r
+ */\r
+public class SettingsMenu extends PopupPanel implements ClickHandler {\r
+\r
+ /**\r
+ * The widget's images.\r
+ */\r
+ private Images images;\r
+ private final MenuBar contextMenu;\r
+ /**\r
+ * An image bundle for this widgets images.\r
+ */\r
+ public interface Images extends ClientBundle,MessagePanel.Images {\r
+\r
+ /**\r
+ * Will bundle the file 'advancedsettings.png' residing in the package\r
+ * 'org.gss_project.gss.web.resources'.\r
+ *\r
+ * @return the image prototype\r
+ */\r
+ @Source("org/gss_project/gss/resources/advancedsettings.png")\r
+ ImageResource preferences();\r
+\r
+ @Source("org/gss_project/gss/resources/lock.png")\r
+ ImageResource credentials();\r
+\r
+ }\r
+\r
+ /**\r
+ * The widget's constructor.\r
+ *\r
+ * @param newImages the image bundle passed on by the parent object\r
+ */\r
+ public SettingsMenu(final Images newImages) {\r
+ // The popup's constructor's argument is a boolean specifying that it\r
+ // auto-close itself when the user clicks outside of it.\r
+ super(true);\r
+ setAnimationEnabled(true);\r
+ images = newImages;\r
+\r
+ Command userCredentialsCommand = new Command(){\r
+ @Override\r
+ public void execute() {\r
+ CredentialsDialog dlg = new CredentialsDialog(newImages);\r
+ dlg.center();\r
+ }\r
+ };\r
+ contextMenu = new MenuBar(true);\r
+// contextMenu.addItem("<span>" + newImages.preferences().getHTML() + " Preferences</span>", true, cmd);\r
+ MenuItem showCredentialsItem = new MenuItem("<span>" + AbstractImagePrototype.create(newImages.credentials()).getHTML() + " Show Credentials</span>", true, userCredentialsCommand);\r
+ showCredentialsItem.getElement().setId("topMenu.settingsMenu.showCredentials");\r
+ contextMenu.addItem(showCredentialsItem);\r
+ \r
+ add(contextMenu);\r
+ // setStyleName("toolbarPopup");\r
+ }\r
+\r
+ @Override\r
+ public void onClick(final ClickEvent event) {\r
+ final SettingsMenu menu = new SettingsMenu(images);\r
+ final int left = event.getRelativeElement().getAbsoluteLeft();\r
+ final int top = event.getRelativeElement().getAbsoluteTop() + event.getRelativeElement().getOffsetHeight();\r
+ menu.setPopupPosition(left, top);\r
+\r
+ menu.show();\r
+ }\r
+\r
+\r
+ /**\r
+ * Retrieve the contextMenu.\r
+ *\r
+ * @return the contextMenu\r
+ */\r
+ public MenuBar getContextMenu() {\r
+ contextMenu.setAutoOpen(false);\r
+ return contextMenu;\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.cell.client.Cell.Context;
+import com.google.gwt.cell.client.ClickableTextCell;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.safehtml.client.SafeHtmlTemplates;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.safehtml.shared.SafeHtmlUtils;
+import com.google.gwt.user.cellview.client.Header;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+
+/**
+ * A {@link Header} subclass that maintains sorting state and displays an icon
+ * to indicate the sort direction.
+ */
+public class SortableHeader extends Header<String> {
+
+ interface Template extends SafeHtmlTemplates {
+ @Template("<div style=\"position:relative;cursor:hand;cursor:pointer;"
+ + "padding-right:{0}px;\">{1}<div>{2}</div></div>")
+ SafeHtml sorted(int imageWidth, SafeHtml arrow, String text);
+
+ @Template("<div style=\"position:relative;cursor:hand;cursor:pointer;"
+ + "padding-right:{0}px;\"><div style=\"position:absolute;display:none;"
+ + "\"></div><div>{1}</div></div>")
+ SafeHtml unsorted(int imageWidth, String text);
+ }
+
+ private static Template template;
+
+ /**
+ * Image resources.
+ */
+ public static interface Resources extends ClientBundle {
+
+ ImageResource downArrow();
+
+ ImageResource upArrow();
+ }
+
+ private static final Resources RESOURCES = GWT.create(Resources.class);
+ private static final int IMAGE_WIDTH = 16;
+ private static final SafeHtml DOWN_ARROW = makeImage(RESOURCES.downArrow());
+ private static final SafeHtml UP_ARROW = makeImage(RESOURCES.upArrow());
+
+ private static SafeHtml makeImage(ImageResource resource) {
+ AbstractImagePrototype proto = AbstractImagePrototype.create(resource);
+ String html = proto.getHTML().replace("style='",
+ "style='position:absolute;right:0px;top:0px;");
+ return SafeHtmlUtils.fromTrustedString(html);
+ }
+
+ private boolean reverseSort = false;
+ private boolean sorted = false;
+ private String text;
+
+ SortableHeader(String text) {
+ super(new ClickableTextCell());
+ if (template == null) {
+ template = GWT.create(Template.class);
+ }
+ this.text = text;
+ }
+
+ public boolean getReverseSort() {
+ return reverseSort;
+ }
+
+ @Override
+ public String getValue() {
+ return text;
+ }
+
+ @Override
+ public void render(Context context, SafeHtmlBuilder sb) {
+ if (sorted) {
+ sb.append(template.sorted(IMAGE_WIDTH, reverseSort ? DOWN_ARROW : UP_ARROW, text));
+ } else {
+ sb.append(template.unsorted(IMAGE_WIDTH, text));
+ }
+ }
+
+ public void setReverseSort(boolean reverseSort) {
+ this.reverseSort = reverseSort;
+ }
+
+ public void setSorted(boolean sorted) {
+ this.sorted = sorted;
+ }
+
+ public void toggleReverseSort() {
+ this.reverseSort = !this.reverseSort;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.QuotaHolder;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+
+/**
+ * The panel that displays a status bar with quota information.
+ */
+public class StatusPanel extends Composite {
+ public static final boolean DONE = false;
+ private HTML fileCountLabel = new HTML("");
+ private HTML fileSizeLabel = new HTML("");
+ private HTML quotaIcon = new HTML("");
+ private HTML quotaLabel = new HTML("");
+ private HTML lastLoginLabel = new HTML("");
+ private HTML currentLoginLabel = new HTML("");
+ private HTML currentlyShowingLabel = new HTML("");
+
+ /**
+ * An image bundle for this widget's images.
+ */
+ public interface Images extends ClientBundle {
+
+ @Source("org/gss_project/gss/resources/windowlist.png")
+ ImageResource totalFiles();
+
+ @Source("org/gss_project/gss/resources/database.png")
+ ImageResource totalSize();
+
+ @Source("org/gss_project/gss/resources/redled.png")
+ ImageResource redSize();
+
+ @Source("org/gss_project/gss/resources/greenled.png")
+ ImageResource greenSize();
+
+ @Source("org/gss_project/gss/resources/yellowled.png")
+ ImageResource yellowSize();
+
+ @Source("org/gss_project/gss/resources/xclock.png")
+ ImageResource lastLogin();
+ }
+
+ private final Images images;
+
+ /**
+ * The constructor of the status panel.
+ *
+ * @param theImages the supplied images
+ */
+ public StatusPanel(Images theImages) {
+ images = theImages;
+ HorizontalPanel outer = new HorizontalPanel();
+ outer.setWidth("100%");
+ outer.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
+
+ HorizontalPanel left = new HorizontalPanel();
+ left.setSpacing(8);
+ HorizontalPanel middle = new HorizontalPanel();
+ middle.setSpacing(8);
+ HorizontalPanel right = new HorizontalPanel();
+ right.setSpacing(8);
+ outer.add(left);
+ outer.add(middle);
+ outer.add(right);
+ left.add(new HTML("<b>Totals:</b> "));
+ left.add(AbstractImagePrototype.create(images.totalFiles()).createImage());
+ left.add(fileCountLabel);
+ left.add(AbstractImagePrototype.create(images.totalSize()).createImage());
+ left.add(fileSizeLabel);
+ quotaIcon.setHTML(AbstractImagePrototype.create(images.greenSize()).getHTML());
+ left.add(quotaIcon);
+ left.add(quotaLabel);
+ middle.add(AbstractImagePrototype.create(images.lastLogin()).createImage());
+ middle.add(new HTML("<b>Last login:</b> "));
+ middle.add(lastLoginLabel);
+ middle.add(new HTML("<b>\u0387 Current session login:</b> "));
+ middle.add(currentLoginLabel);
+ right.add(currentlyShowingLabel);
+ outer.setStyleName("statusbar-inner");
+ left.setStyleName("statusbar-inner");
+ middle.setStyleName("statusbar-inner");
+ right.setStyleName("statusbar-inner");
+ outer.setCellHorizontalAlignment(right, HasHorizontalAlignment.ALIGN_RIGHT);
+
+ initWidget(outer);
+
+ // Initialize and display the quota information.
+ DeferredCommand.addCommand(new IncrementalCommand() {
+ @Override
+ public boolean execute() {
+ GSS app = GSS.get();
+ UserResource user = app.getCurrentUserResource();
+ if (user == null || app.getTreeView().getMyFolders() == null)
+ return !DONE;
+ displayStats(user);
+ return DONE;
+ }
+ });
+ }
+
+ /**
+ * Refresh the widget with the provided statistics.
+ */
+ private void displayStats(UserResource user) {
+ QuotaHolder stats = user.getQuota();
+ if (stats.getFileCount() == 1)
+ fileCountLabel.setHTML("1 file");
+ else
+ fileCountLabel.setHTML(stats.getFileCount() + " files");
+ fileSizeLabel.setHTML(stats.getFileSizeAsString() + " used");
+ long pc = stats.percentOfFreeSpace();
+ if(pc<10) {
+ quotaIcon.setHTML(AbstractImagePrototype.create(images.redSize()).getHTML());
+ quotaLabel.setHTML(stats.getQuotaLeftAsString() +" free");
+ } else if(pc<20) {
+ quotaIcon.setHTML(AbstractImagePrototype.create(images.yellowSize()).getHTML());
+ quotaLabel.setHTML(stats.getQuotaLeftAsString() +" free");
+ } else {
+ quotaIcon.setHTML(AbstractImagePrototype.create(images.greenSize()).getHTML());
+ quotaLabel.setHTML(stats.getQuotaLeftAsString() +" free");
+ }
+ final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
+ lastLoginLabel.setHTML(formatter.format(user.getLastLogin()));
+ currentLoginLabel.setHTML(formatter.format(user.getCurrentLogin()));
+ }
+
+ /**
+ * Requests updated quota information from the server and refreshes
+ * the display.
+ */
+ public void updateStats() {
+ final GSS app = GSS.get();
+ UserResource user = app.getCurrentUserResource();
+ GetCommand<UserResource> uc = new GetCommand<UserResource>(UserResource.class, user.getUri(), null){
+ @Override
+ public void onComplete() {
+ displayStats(getResult());
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ if(t instanceof RestException)
+ app.displayError("Unable to fetch quota:" +
+ ((RestException)t).getHttpStatusText());
+ else
+ app.displayError("System error fetching quota:" +
+ t.getMessage());
+ GWT.log("ERR", t);
+ }
+ };
+ DeferredCommand.addCommand(uc);
+ }
+
+ /**
+ * Displays the statistics for the current folder.
+ *
+ * @param text the statistics to display
+ */
+ public void updateCurrentlyShowing(String text) {
+ if (text == null)
+ currentlyShowingLabel.setText("");
+ else
+ currentlyShowingLabel.setHTML(" <b>Showing:</b> " + text);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.MenuBar;
+import com.google.gwt.user.client.ui.MenuItem;
+
+/**
+ * The top panel, which contains the menu bar icons and the user name.
+ */
+public class TopPanel extends Composite {
+
+ /**
+ * A constant that denotes the completion of an IncrementalCommand.
+ */
+ public static final boolean DONE = false;
+
+ /**
+ * An image bundle for this widgets images.
+ */
+ public interface Images extends ClientBundle, FileMenu.Images, EditMenu.Images,
+ SettingsMenu.Images, GroupMenu.Images, FilePropertiesDialog.Images,
+ HelpMenu.Images, LoadingIndicator.Images {
+
+ @Source("org/gss_project/gss/resources/exit.png")
+ ImageResource exit();
+
+ @Source("org/gss_project/gss/resources/folder_blue.png")
+ ImageResource folder();
+
+ @Source("org/gss_project/gss/resources/edit.png")
+ ImageResource edit();
+
+ @Source("org/gss_project/gss/resources/edit_group.png")
+ ImageResource group();
+
+ @Source("org/gss_project/gss/resources/configure.png")
+ ImageResource configure();
+
+ @Source("org/gss_project/gss/resources/help.png")
+ ImageResource help();
+
+ @Source("org/gss_project/gss/resources/pithos-logo.png")
+ ImageResource gssLogo();
+
+ @Source("org/gss_project/gss/resources/grnet-logo.png")
+ ImageResource grnetLogo();
+ }
+
+ /**
+ * The menu bar widget.
+ */
+ private MenuBar menu;
+
+ /**
+ * The file menu widget.
+ */
+ private FileMenu fileMenu;
+
+ /**
+ * The edit menu widget.
+ */
+ private EditMenu editMenu;
+
+ /**
+ * The group menu widget.
+ */
+ private GroupMenu groupMenu;
+
+ /**
+ * The settings menu widget.
+ */
+ private SettingsMenu settingsMenu;
+
+ /**
+ * The help menu widget.
+ */
+ private HelpMenu helpMenu;
+
+ /**
+ * A widget that displays a message indicating that communication with the
+ * server is underway.
+ */
+ private LoadingIndicator loading;
+
+ /**
+ * The constructor for the top panel.
+ *
+ * @param images the supplied images
+ */
+ public TopPanel(Images images) {
+ fileMenu = new FileMenu(images);
+ editMenu = new EditMenu(images);
+ groupMenu = new GroupMenu(images);
+ settingsMenu = new SettingsMenu(images);
+ helpMenu = new HelpMenu(images);
+ loading = new LoadingIndicator(images);
+ HorizontalPanel outer = new HorizontalPanel();
+
+ outer.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
+
+ menu = new MenuBar();
+ menu.setWidth("100%");
+ menu.setAutoOpen(false);
+ menu.setAnimationEnabled(true);
+ menu.setStyleName("toolbarmenu");
+
+ Command quitCommand = new Command(){
+ @Override
+ public void execute() {
+ QuitDialog dlg = new QuitDialog();
+ dlg.center();
+ }
+ };
+ MenuItem quitItem = new MenuItem("<table style='font-size: 100%'><tr><td>" +
+ AbstractImagePrototype.create(images.exit()).getHTML() + "</td><td>Quit</td></tr></table>", true, quitCommand);
+ quitItem.getElement().setId("topMenu.quit");
+
+ MenuItem fileItem = new MenuItem("<table style='font-size: 100%'><tr><td>" +
+ AbstractImagePrototype.create(images.folder()).getHTML() + "</td><td>File</td></tr></table>", true, new MenuBar(true)){
+ @Override
+ public MenuBar getSubMenu() {
+ return fileMenu.createMenu();
+ }
+ };
+ fileItem.getElement().setId("topMenu.file");
+
+ MenuItem editItem = new MenuItem("<table style='font-size: 100%'><tr><td>" +
+ AbstractImagePrototype.create(images.edit()).getHTML() + "</td><td>Edit</td></tr></table>", true, new MenuBar(true)){
+ @Override
+ public MenuBar getSubMenu() {
+ return editMenu.createMenu();
+ }
+ };
+ editItem.getElement().setId("topMenu.edit");
+
+ MenuItem groupItem = new MenuItem("<table style='font-size: 100%'><tr><td>" +
+ AbstractImagePrototype.create(images.group()).getHTML() + "</td><td>Group</td></tr></table>", true,
+ groupMenu.getContextMenu());
+ groupItem.getElement().setId("topMenu.group");
+
+ MenuItem configureItem = new MenuItem("<table style='font-size: 100%'><tr><td>" +
+ AbstractImagePrototype.create(images.configure()).getHTML() + "</td><td>Settings</td></tr></table>",
+ true,settingsMenu.getContextMenu());
+ configureItem.getElement().setId("topMenu.settings");
+
+ MenuItem helpItem = new MenuItem("<table style='font-size: 100%'><tr><td>" +
+ AbstractImagePrototype.create(images.help()).getHTML() + "</td><td>Help</td></tr></table>", true, new MenuBar(true)){
+ @Override
+ public MenuBar getSubMenu() {
+ return helpMenu.createMenu();
+ }
+ };
+ helpItem.getElement().setId("topMenu.help");
+
+ menu.addItem(quitItem);
+ menu.addItem(fileItem);
+ menu.addItem(editItem);
+ menu.addItem(groupItem);
+ menu.addItem(configureItem);
+ menu.addItem(helpItem);
+
+ outer.setSpacing(2);
+ outer.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
+ outer.setCellVerticalAlignment(menu, HasVerticalAlignment.ALIGN_MIDDLE);
+ outer.add(menu);
+ outer.setStyleName("toolbar");
+
+ outer.add(loading);
+
+ Configuration conf = (Configuration) GWT.create(Configuration.class);
+ String path = Window.Location.getPath();
+ String baseUrl = GWT.getModuleBaseURL();
+ String homeUrl = baseUrl.substring(0, baseUrl.indexOf(path));
+ HTML logos = new HTML("<table><tr><td><a href='" + homeUrl +
+ "' target='gss'>" + AbstractImagePrototype.create(images.gssLogo()).getHTML() +
+ "</a><a href='http://www.grnet.gr/' " + "target='grnet'>" +
+ AbstractImagePrototype.create(images.grnetLogo()).getHTML()+"</a></td></tr></table>");
+ outer.add(logos);
+
+ outer.setCellHorizontalAlignment(logos, HasHorizontalAlignment.ALIGN_RIGHT);
+
+ initWidget(outer);
+ }
+
+
+ /**
+ * Retrieve the loading.
+ *
+ * @return the loading
+ */
+ public LoadingIndicator getLoading() {
+ return loading;
+ }
+
+ /**
+ * Retrieve the fileMenu.
+ *
+ * @return the fileMenu
+ */
+ FileMenu getFileMenu() {
+ return fileMenu;
+ }
+
+ /**
+ * Retrieve the editMenu.
+ *
+ * @return the editMenu
+ */
+ EditMenu getEditMenu() {
+ return editMenu;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+
+/**
+ * @author kman
+ *
+ */
+public interface Updateable {
+ public void update();
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import org.gss_project.gss.web.client.rest.resource.UserSearchResource;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.KeyUpEvent;
+import com.google.gwt.event.dom.client.KeyUpHandler;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
+import com.google.gwt.user.client.ui.SuggestBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+/**
+ * @author kman
+ */
+public class UserAddDialog extends DialogBox {
+
+ private MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
+ private SuggestBox suggestBox = new SuggestBox(oracle);
+
+ String selectedUser=null;
+ FlexTable userTable = new FlexTable();
+
+ /**
+ * The widget's constructor.
+ */
+ public UserAddDialog() {
+ setAnimationEnabled(true);
+ setText("Add User");
+ VerticalPanel panel = new VerticalPanel();
+ setWidget(panel);
+ panel.addStyleName("gss-TabPanelBottom");
+ userTable.addStyleName("gss-permList");
+ userTable.setWidget(0, 0, new Label("Username:"));
+ userTable.getFlexCellFormatter().setStyleName(0, 0, "props-toplabels");
+ suggestBox.getTextBox().addFocusHandler(new FocusHandler() {
+
+ @Override
+ public void onFocus(FocusEvent event) {
+ if (selectedUser != null && selectedUser.endsWith("@"))
+ updateSuggestions();
+ }
+ });
+
+ suggestBox.addKeyUpHandler(new KeyUpHandler() {
+
+ @Override
+ public void onKeyUp(KeyUpEvent event) {
+ // Ignore the arrow keys.
+ int keyCode=event.getNativeKeyCode();
+ if(keyCode == KeyCodes.KEY_UP ||
+ keyCode == KeyCodes.KEY_DOWN ||
+ keyCode == KeyCodes.KEY_LEFT ||
+ keyCode == KeyCodes.KEY_RIGHT)
+ return;
+ if (keyCode==KeyCodes.KEY_ESCAPE) {
+ suggestBox.hideSuggestionList();
+ return;
+ }
+ String text = suggestBox.getText().trim();
+ // Avoid useless queries for keystrokes that do not modify the
+ // text.
+ if (text.equals(selectedUser))
+ return;
+ selectedUser = text;
+ // Go to the server only if the user typed the @ character.
+ if (selectedUser.endsWith("@"))
+ updateSuggestions();
+ }
+ });
+ suggestBox.getElement().setId("addUser.textBox");
+ userTable.setWidget(0, 1, suggestBox);
+ panel.add(userTable);
+ HorizontalPanel buttons = new HorizontalPanel();
+ Button ok = new Button("OK", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ addUser();
+ hide();
+ }
+ });
+ ok.getElement().setId("addUser.button.ok");
+ buttons.add(ok);
+ buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);
+ // Create the 'Cancel' button, along with a listener that hides the
+ // dialog when the button is clicked.
+ Button cancel = new Button("Cancel", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
+ cancel.getElement().setId("addUser.button.cancel");
+ buttons.add(cancel);
+ buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
+ buttons.setSpacing(8);
+ buttons.addStyleName("gss-TabPanelBottom");
+ panel.add(buttons);
+ panel.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
+ panel.addStyleName("gss-DialogBox");
+ }
+
+ @Override
+ public void center() {
+ super.center();
+ suggestBox.setFocus(true);
+ }
+
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals("keydown"))
+ // Use the popup's key preview hooks to close the dialog when either
+ // enter or escape is pressed.
+ switch (evt.getKeyCode()) {
+ case KeyCodes.KEY_ENTER:
+ addUser();
+ hide();
+ break;
+ case KeyCodes.KEY_ESCAPE:
+ hide();
+ break;
+ }
+ }
+
+ /**
+ * Generate a request to add a user to a group.
+ *
+ * @param groupName the name of the group to create
+ */
+ private void addUser() {
+ GroupResource group = (GroupResource) GSS.get().getCurrentSelection();
+ selectedUser = suggestBox.getText();
+ if ( group == null ) {
+ GSS.get().displayError("Empty group name!");
+ return;
+ }
+ if ( selectedUser == null ) {
+ GSS.get().displayError("No User Selected!");
+ return;
+ }
+ PostCommand cg = new PostCommand(group.getUri()+"?name="+selectedUser, "", 201){
+ @Override
+ public void onComplete() {
+ GSS.get().getGroups().updateGroups();
+ GSS.get().showUserList();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("User does not exist");
+ else if(statusCode == 409)
+ GSS.get().displayError("A user with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to add user: "+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error adding user: "+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cg);
+ }
+
+ /**
+ * Update the list of suggestions.
+ */
+ protected void updateSuggestions() {
+ final GSS app = GSS.get();
+ String query = selectedUser.substring(0, selectedUser.length()-1);
+ GWT.log("Searching for " + query, null);
+
+ GetCommand<UserSearchResource> eg = new GetCommand<UserSearchResource>(UserSearchResource.class,
+ app.getApiPath() + "users/" + URL.encodeComponent(query), false, null) {
+
+ @Override
+ public void onComplete() {
+ suggestBox.hideSuggestionList();
+ oracle.clear();
+ UserSearchResource s = getResult();
+ for (UserResource user : s.getUsers()) {
+ GWT.log("Found " + user.getUsername(), null);
+ oracle.add(user.getUsername());
+ }
+ suggestBox.showSuggestionList();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ if(t instanceof RestException)
+ app.displayError("Unable to perform search: "+((RestException)t).getHttpStatusText());
+ else
+ app.displayError("System error while searching for users: "+t.getMessage());
+ GWT.log("", t);
+ DisplayHelper.log(t.getMessage());
+ }
+
+ };
+ DeferredCommand.addCommand(eg);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+
+/**
+ * The panel that displays a status bar with quota information.
+ */
+public class UserDetailsPanel extends Composite {
+ public static final boolean DONE = false;
+
+ /**
+ * The label that displays user information.
+ */
+ private HTML userInfoLabel;
+
+ /**
+ * The constructor of the user details panel.
+ */
+ public UserDetailsPanel() {
+ final HorizontalPanel outer = new HorizontalPanel();
+ outer.setSpacing(8);
+ userInfoLabel = new HTML(" ");
+ outer.add(userInfoLabel);
+ outer.setCellHorizontalAlignment(userInfoLabel, HasHorizontalAlignment.ALIGN_RIGHT);
+ outer.setStyleName("statusbar-inner");
+
+ initWidget(outer);
+
+ DeferredCommand.addCommand(new IncrementalCommand() {
+
+ @Override
+ public boolean execute() {
+ return displayUserInfo();
+ }
+ });
+ }
+
+ /**
+ * Display the user information on the panel.
+ *
+ * @return true if the work has been carried out successfully
+ */
+ protected boolean displayUserInfo() {
+ UserResource user = GSS.get().getCurrentUserResource();
+ if (user == null)
+ return !DONE;
+ userInfoLabel.setHTML("<b>" + user.getName() + " \u0387 " + user.getUsername() + "</b>");
+ GSS.get().putUserToMap(user.getUsername(), user.getName());
+ return DONE;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client;
+
+import org.gss_project.gss.web.client.FilePropertiesDialog.Images;
+import org.gss_project.gss.web.client.rest.DeleteCommand;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import org.gss_project.gss.web.client.rest.resource.UserSearchResource;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+/**
+ * @author kman
+ */
+public class VersionsList extends Composite {
+
+ int selectedRow = -1;
+
+ int permissionCount = -1;
+
+ List<FileResource> versions = null;
+
+ final Images images;
+
+ final VerticalPanel permPanel = new VerticalPanel();
+
+ final FlexTable permTable = new FlexTable();
+
+ FileResource toRemove = null;
+
+ FilePropertiesDialog container;
+
+ public VersionsList(FilePropertiesDialog aContainer, final Images theImages, List<FileResource> theVersions) {
+ images = theImages;
+ container = aContainer;
+ versions = theVersions;
+ Collections.sort(theVersions, new Comparator<FileResource>(){
+
+ @Override
+ public int compare(FileResource o1, FileResource o2) {
+ return o1.getVersion().compareTo(o2.getVersion());
+ }
+
+ });
+ permTable.setText(0, 0, "Version");
+ permTable.setText(0, 1, "Created");
+ permTable.setText(0, 2, "Modified");
+ permTable.setText(0, 3, "Size");
+ permTable.setText(0, 4, "");
+ permTable.setText(0, 5, "");
+ permTable.getFlexCellFormatter().setStyleName(0, 0, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 1, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 2, "props-toplabels");
+ permTable.getFlexCellFormatter().setStyleName(0, 3, "props-toplabels");
+ permTable.getFlexCellFormatter().setColSpan(0, 1, 2);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(0, 1, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(0, 2, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(0, 3, HasHorizontalAlignment.ALIGN_CENTER);
+ permPanel.add(permTable);
+ permPanel.addStyleName("gss-TabPanelBottom");
+ permTable.addStyleName("gss-permList");
+ initWidget(permPanel);
+ updateTable();
+ }
+
+ public void updateTable() {
+ copyListAndContinue(versions);
+ }
+
+ public void showVersionsTable(){
+ int i = 1;
+ if (toRemove != null) {
+ versions.remove(toRemove);
+ toRemove = null;
+ }
+ for (final FileResource dto : versions) {
+ HTML restoreVersion = new HTML("<a href='#' class='hidden-link info'><span>"+AbstractImagePrototype.create(images.restore()).getHTML()+"</span><div>Restore this Version</div></a>");
+ restoreVersion.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ restoreVersion(dto);
+ }
+ });
+
+ permTable.setHTML(i, 0, "<span>" + dto.getVersion() + "</span>");
+ permTable.setHTML(i, 1, "<span>" + formatDate(dto.getCreationDate()) + " by " + GSS.get().findUserFullName(dto.getCreatedBy()) + "</span>");
+ permTable.setHTML(i, 2, "<span>" + formatDate(dto.getModificationDate()) + " by " + GSS.get().findUserFullName(dto.getModifiedBy()) + "</span>");
+ permTable.setHTML(i, 3, "<span>" + dto.getFileSizeAsString() + "</span>");
+ HTML downloadHtml = new HTML("<a class='hidden-link info' href='#'><span>"+AbstractImagePrototype.create(images.download()).getHTML()+"</span><div>View this Version</div></a>");
+ downloadHtml.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ GSS app = GSS.get();
+ String dateString = RestCommand.getDate();
+ String resource = dto.getUri().substring(app.getApiPath().length()-1, dto.getUri().length());
+ String sig = app.getCurrentUserResource().getUsername()+" "+RestCommand.calculateSig("GET", dateString, resource, RestCommand.base64decode(app.getToken()));
+ String fileUrl = dto.getUri() + "?version=" + dto.getVersion() + "&Authorization=" + URL.encodeComponent(sig) + "&Date="+URL.encodeComponent(dateString);
+ Window.open(fileUrl, "_BLANK", "");
+ }
+ });
+ permTable.setWidget(i, 4, downloadHtml);
+ permTable.setWidget(i, 5, restoreVersion);
+ permTable.getFlexCellFormatter().setStyleName(i, 0, "props-labels");
+ permTable.getFlexCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(i, 1, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setColSpan(i, 1, 2);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(i, 2, HasHorizontalAlignment.ALIGN_CENTER);
+ permTable.getFlexCellFormatter().setHorizontalAlignment(i, 3, HasHorizontalAlignment.ALIGN_CENTER);
+ i++;
+ }
+ for (; i < permTable.getRowCount(); i++)
+ permTable.removeRow(i);
+ }
+
+ void removeVersion(final FileResource version) {
+ DeleteCommand df = new DeleteCommand(version.getUri()){
+
+ @Override
+ public void onComplete() {
+ toRemove = version;
+ updateTable();
+ GSS.get().getTreeView().refreshCurrentNode(false);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("Versions does not exist");
+ else
+ GSS.get().displayError("Unable to remove version:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error removing version:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(df);
+
+ }
+
+ void restoreVersion(final FileResource version) {
+ FileResource selectedFile = (FileResource) GSS.get().getCurrentSelection();
+ PostCommand ep = new PostCommand(selectedFile.getUri()+"?restoreVersion="+version.getVersion(),"",200){
+
+
+ @Override
+ public void onComplete() {
+ container.hide();
+ GSS.get().getTreeView().refreshCurrentNode(false);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException)
+ GSS.get().displayError("Unable to restore version:"+((RestException)t).getHttpStatusText());
+ else
+ GSS.get().displayError("System error restoring version:"+t.getMessage());
+ }
+
+ };
+ DeferredCommand.addCommand(ep);
+ }
+
+ private String formatDate(Date date){
+ DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy : HH:mm");
+ return format.format(date);
+ }
+
+ /**
+ * Copies the input List to a new List
+ * @param input
+ */
+ private void copyListAndContinue(List<FileResource> input){
+ List<FileResource> copiedInput = new ArrayList<FileResource>();
+ for(FileResource dto : input) {
+ copiedInput.add(dto);
+ }
+ handleFullNames(copiedInput);
+ }
+
+ /**
+ * Examines whether or not the user's full name exists in the
+ * userFullNameMap in the GSS.java for every element of the input list.
+ * If the user's full name does not exist in the map then a request is being made
+ * for the specific username.
+ *
+ * @param input
+ */
+ private void handleFullNames(List<FileResource> input){
+ if(input.isEmpty()){
+ showVersionsTable();
+ return;
+ }
+
+ if(GSS.get().findUserFullName(input.get(0).getOwner()) == null){
+ findFullNameAndUpdate(input);
+ return;
+ }
+
+ if(input.size() >= 1){
+ input.remove(input.get(0));
+ if(input.isEmpty()){
+ showVersionsTable();
+ }else{
+ handleFullNames(input);
+ }
+ }
+ }
+
+ /**
+ * Makes a request to search for full name from a given username
+ * and continues checking the next element of the List.
+ *
+ * @param input
+ */
+
+ private void findFullNameAndUpdate(final List<FileResource> input){
+ final String aUserName = input.get(0).getOwner();
+ String path = GSS.get().getApiPath() + "users/" + aUserName;
+
+ GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
+ @Override
+ public void onComplete() {
+ final UserSearchResource result = getResult();
+ for (UserResource user : result.getUsers()){
+ String username = user.getUsername();
+ String userFullName = user.getName();
+ GSS.get().putUserToMap(username, userFullName);
+ if(input.size() >= 1){
+ input.remove(input.get(0));
+ if(input.isEmpty()){
+ showVersionsTable();
+ return;
+ }
+ handleFullNames(input);
+ }
+ }
+ }
+ @Override
+ public void onError(Throwable t) {
+ GSS.get().displayError("Unable to fetch user's full name from the given username " + aUserName);
+ if(input.size() >= 1){
+ input.remove(input.get(0));
+ handleFullNames(input);
+ }
+ }
+ };
+ DeferredCommand.addCommand(gg);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.animation;
+
+import com.google.gwt.animation.client.Animation;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
+
+
+/**
+ * @author kman
+ *
+ */
+public class FadeIn extends Animation {
+ Widget widget;
+ int initialOpacity = 100;
+ double currOpacity = 100;
+
+ public FadeIn(Widget aWidget){
+ widget = aWidget;
+ }
+
+ @Override
+ protected void onUpdate(double progress) {
+ if(currOpacity > 0.0){
+ progress = 1.0 - progress;
+ currOpacity = initialOpacity * progress;
+ DOM.setStyleAttribute(widget.getElement(), "opacity", ""+new Double(1d - currOpacity / 100d));
+ //required for ie to work
+ //Disabled because IE has bugs rendering non-opaque objects
+ //int opacityToSet = new Double(currOpacity).intValue();
+ //DOM.setStyleAttribute(widget.getElement(), "filter", "alpha(opacity=" + (initialOpacity - opacityToSet) + ")");
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.animation;
+
+import com.google.gwt.animation.client.Animation;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
+
+
+/**
+ * @author kman
+ *
+ */
+public class FadeOut extends Animation {
+ Widget widget;
+
+ int initialOpacity = 100;
+ double currOpacity = 100;
+
+ public FadeOut(Widget aWidget){
+ widget = aWidget;
+ }
+
+ @Override
+ protected void onUpdate(double progress) {
+ if(currOpacity>0.0){
+ progress = 1.0 - progress;
+ currOpacity = initialOpacity*progress;
+ DOM.setStyleAttribute(widget.getElement(), "opacity", ""+new Double(currOpacity/100d));
+ //required for ie to work
+ //Disabled because IE has bugs rendering non-opaque objects
+ //int opacityToSet = new Double(currOpacity).intValue();
+ //DOM.setStyleAttribute(widget.getElement(), "filter", "alpha(opacity="+currOpacity+")");
+ }
+ }
+
+ /*
+ protected void onComplete() {
+ super.onComplete();
+ hpanel.clear();
+ html = new HTML(" ");
+ hpanel.getParent().setVisible(false);
+ }
+ */
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.clipboard;
+
+
+/**
+ * @author koutsoub
+ *
+ */
+public class Clipboard {
+ public final static int CUT=1;
+ public final static int COPY=2;
+ private ClipboardItem item;
+
+ /**
+ * Retrieve the item.
+ *
+ * @return the item
+ */
+ public ClipboardItem getItem() {
+ return item;
+ }
+
+ /**
+ * Modify the item.
+ *
+ * @param anItem the item to set
+ */
+ public void setItem(ClipboardItem anItem) {
+ item = anItem;
+ }
+
+ public boolean hasFolderOrFileItem(){
+ if( item !=null )
+ return item.isFileOrFolder();
+ return false;
+ }
+
+ public boolean hasFileItem(){
+ if( item !=null )
+ return item.isFile();
+ return false;
+ }
+
+ public boolean hasUserItem(){
+ if( item !=null )
+ return item.isUser();
+ return false;
+ }
+
+ public boolean isEmpty(){
+ return item == null;
+ }
+
+ public void clear(){
+ item = null;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.clipboard;
+
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * @author kman
+ *
+ */
+public class ClipboardItem implements Serializable{
+ private int operation;
+ private FileResource file;
+ private List<FileResource> files;
+ private RestResourceWrapper folderResource;
+ private GroupUserResource user;
+
+ public ClipboardItem(){}
+
+ public ClipboardItem(int anOperation, List<FileResource> theFiles){
+ operation = anOperation;
+ files = theFiles;
+ }
+
+ public ClipboardItem(int anOperation, FileResource aFile){
+ operation = anOperation;
+ file = aFile;
+ }
+
+ public ClipboardItem(int anOperation, RestResourceWrapper folder){
+ operation = anOperation;
+ folderResource = folder;
+ }
+ public ClipboardItem(int anOperation, GroupUserResource aUser){
+ operation = anOperation;
+ user = aUser;
+ }
+
+ public ClipboardItem(GroupUserResource aUser){
+ operation = Clipboard.COPY;
+ user = aUser;
+ }
+
+ public ClipboardItem(List<FileResource> theFiles){
+ operation = Clipboard.COPY;
+ files = theFiles;
+ }
+
+ public ClipboardItem(FileResource aFile){
+ operation = Clipboard.COPY;
+ file = aFile;
+ }
+
+ public ClipboardItem(RestResourceWrapper folder){
+ operation = Clipboard.COPY;
+ folderResource = folder;
+ }
+
+ /**
+ * Retrieve the user.
+ *
+ * @return the user
+ */
+ public GroupUserResource getUser() {
+ return user;
+ }
+
+ /**
+ * Modify the user.
+ *
+ * @param aUser the user to set
+ */
+ public void setUser(GroupUserResource aUser) {
+ user = aUser;
+ }
+
+ /**
+ * Retrieve the operation.
+ *
+ * @return the operation
+ */
+ public int getOperation() {
+ return operation;
+ }
+
+ /**
+ * Modify the operation.
+ *
+ * @param anOperation the operation to set
+ */
+ public void setOperation(int anOperation) {
+ operation = anOperation;
+ }
+
+ /**
+ * Retrieve the file.
+ *
+ * @return the file
+ */
+ public FileResource getFile() {
+ return file;
+ }
+
+ /**
+ * Modify the file.
+ *
+ * @param aFile the file to set
+ */
+ public void setFile(FileResource aFile) {
+ file = aFile;
+ }
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<FileResource> getFiles() {
+ return files;
+ }
+
+ /**
+ * checks whether the clipboard item is a file or folder
+ */
+ public boolean isFileOrFolder(){
+ if(file !=null || files != null || folderResource != null)
+ return true;
+ return false;
+ }
+
+ /**
+ * checks whether the clipboard item is a file (or files)
+ */
+ public boolean isFile() {
+ if(file !=null || files != null)
+ return true;
+ return false;
+ }
+
+ public boolean isUser(){
+ if( user!=null )
+ return true;
+ return false;
+ }
+
+ /**
+ * Retrieve the folderResource.
+ *
+ * @return the folderResource
+ */
+ public RestResourceWrapper getRestResourceWrapper() {
+ return folderResource;
+ }
+
+ /**
+ * Modify the folderResource.
+ *
+ * @param aFolder the folderResource to set
+ */
+ public void setRestResourceWrapper(RestResourceWrapper aFolder) {
+ folderResource = aFolder;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.clipboard.ClipboardItem;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.List;
+
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.PopupPanel;
+/**
+ *
+ * Command for copying a file, folder or user to GSS Clipboard
+ * @author kman
+ *
+ */
+public class CopyCommand implements Command{
+ private PopupPanel containerPanel;
+
+ public CopyCommand(PopupPanel _containerPanel){
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ Object selection = GSS.get().getCurrentSelection();
+ if (selection == null)
+ return;
+
+ if (selection instanceof RestResourceWrapper) {
+ ClipboardItem clipboardItem = new ClipboardItem((RestResourceWrapper) selection);
+ GSS.get().getClipboard().setItem(clipboardItem);
+ } else if (selection instanceof FileResource) {
+ ClipboardItem clipboardItem = new ClipboardItem((FileResource) selection);
+ GSS.get().getClipboard().setItem(clipboardItem);
+ } else if (selection instanceof GroupUserResource) {
+ ClipboardItem clipboardItem = new ClipboardItem((GroupUserResource) selection);
+ GSS.get().getClipboard().setItem(clipboardItem);
+ }
+ else if (selection instanceof List){
+ ClipboardItem clipboardItem = new ClipboardItem((List<FileResource>) selection);
+ GSS.get().getClipboard().setItem(clipboardItem);
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.clipboard.Clipboard;
+import org.gss_project.gss.web.client.clipboard.ClipboardItem;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ * Command for cutting a file, folder or user to GSS Clipboard
+ * @author kman
+ *
+ */
+public class CutCommand implements Command{
+ private PopupPanel containerPanel;
+
+ public CutCommand( PopupPanel _containerPanel ){
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ Object selection = GSS.get().getCurrentSelection();
+ if (selection == null)
+ return;
+ GWT.log("selection: " + selection.toString(), null);
+ if (selection instanceof RestResourceWrapper) {
+ ClipboardItem clipboardItem = new ClipboardItem(Clipboard.CUT, (RestResourceWrapper) selection);
+ GSS.get().getClipboard().setItem(clipboardItem);
+ } else if (selection instanceof FileResource) {
+ ClipboardItem clipboardItem = new ClipboardItem(Clipboard.CUT, (FileResource) selection);
+ GSS.get().getClipboard().setItem(clipboardItem);
+ } else if (selection instanceof GroupUserResource) {
+ ClipboardItem clipboardItem = new ClipboardItem(Clipboard.CUT, (GroupUserResource) selection);
+ GSS.get().getClipboard().setItem(clipboardItem);
+ }
+ else if (selection instanceof List){
+ ClipboardItem clipboardItem = new ClipboardItem(Clipboard.CUT, (List<FileResource>) selection);
+ GSS.get().getClipboard().setItem(clipboardItem);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.DeleteFileDialog;
+import org.gss_project.gss.web.client.DeleteFolderDialog;
+import org.gss_project.gss.web.client.DeleteGroupDialog;
+import org.gss_project.gss.web.client.EditMenu.Images;
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ * Delete selected object command
+ * @author kman
+ *
+ */
+public class DeleteCommand implements Command{
+ private PopupPanel containerPanel;
+ final Images newImages;
+
+ /**
+ * @param _containerPanel
+ * @param _newImages the images of all the possible delete dialogs
+ */
+ public DeleteCommand( PopupPanel _containerPanel, final Images _newImages ){
+ containerPanel = _containerPanel;
+ newImages=_newImages;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ displayDelete();
+ }
+ /**
+ * Display the delete dialog, according to the selected object.
+ *
+ *
+ */
+ void displayDelete() {
+ Object selection = GSS.get().getCurrentSelection();
+ if (selection == null)
+ return;
+ GWT.log("selection: " + selection.toString(), null);
+ if (selection instanceof RestResourceWrapper) {
+ DeleteFolderDialog dlg = new DeleteFolderDialog(newImages);
+ dlg.center();
+ } else if (selection instanceof FileResource || selection instanceof List) {
+ DeleteFileDialog dlg = new DeleteFileDialog(newImages);
+ dlg.center();
+ } else if (selection instanceof GroupUserResource) {
+ // TODO implement user deletion
+ } else if (selection instanceof GroupResource) {
+ DeleteGroupDialog dlg = new DeleteGroupDialog(newImages);
+ dlg.center();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.DeleteGroupDialog;
+import org.gss_project.gss.web.client.DeleteUserDialog;
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.Groups.Images;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class DeleteUserOrGroupCommand implements Command{
+ private PopupPanel containerPanel;
+ final Images images;
+
+ /**
+ * @param aContainerPanel
+ * @param newImages the images of the new folder dialog
+ */
+ public DeleteUserOrGroupCommand(PopupPanel aContainerPanel, final Images newImages){
+ containerPanel = aContainerPanel;
+ images = newImages;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ if(GSS.get().getCurrentSelection() instanceof GroupResource)
+ displayNewGroup();
+ else if(GSS.get().getCurrentSelection() instanceof GroupUserResource)
+ displayNewUser();
+ else
+ GSS.get().displayError("No user or group selected");
+ }
+
+ void displayNewGroup() {
+ DeleteGroupDialog dlg = new DeleteGroupDialog(images);
+ dlg.center();
+ }
+
+ void displayNewUser() {
+ DeleteUserDialog dlg = new DeleteUserDialog(images);
+ dlg.center();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.DeleteCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ * Command to empty trash bin.
+ *
+ * @author kman
+ */
+public class EmptyTrashCommand implements Command{
+ private PopupPanel containerPanel;
+
+ public EmptyTrashCommand(PopupPanel _containerPanel){
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ DeleteCommand df = new DeleteCommand(GSS.get().getTreeView().getTrash().getUri()){
+
+ @Override
+ public void onComplete() {
+ GSS.get().getTreeView().updateTrashNode();
+ GSS.get().showFileList(true);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("Resource does not exist");
+ else
+ GSS.get().displayError("Unable to empty trash:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error emptying trash:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(df);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import org.gss_project.gss.web.client.rest.resource.UserSearchResource;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+
+
+/**
+ * This command manages usernames and the corresponding user's Full Name
+ * along with the HashMap collection in the GSS.java class
+ *
+ * @author natasa
+ *
+ */
+public class GetUserCommand implements Command{
+
+ /**
+ * User's username e.g johndoe@somewhere.com
+ */
+ private String userName;
+
+ public GetUserCommand(String _userName){
+ userName = _userName;
+ }
+
+ @Override
+ public void execute() {
+ String path = GSS.get().getApiPath() + "users/" + userName;
+ GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class,
+ path, false ,null) {
+ @Override
+ public void onComplete() {
+ final UserSearchResource result = getResult();
+ for (UserResource user : result.getUsers()){
+ String username = user.getUsername();
+ String _userFullName = user.getName();
+ GSS.get().putUserToMap(username, _userFullName);
+ }
+ }
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch user's full name from the given username " + userName);
+ }
+ };
+ DeferredCommand.addCommand(gg);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.FileMenu.Images;
+import org.gss_project.gss.web.client.FolderPropertiesDialog;
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupsResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * Display the 'new folder' dialog for creating a new folder.
+ * @author kman
+ *
+ */
+public class NewFolderCommand implements Command{
+ private PopupPanel containerPanel;
+ final Images images;
+
+ private List<GroupResource> groups = null;
+
+ /**
+ * @param aContainerPanel
+ * @param newImages the images of the new folder dialog
+ */
+ public NewFolderCommand(PopupPanel aContainerPanel, final Images newImages){
+ containerPanel = aContainerPanel;
+ images=newImages;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ getGroups();
+ DeferredCommand.addCommand(new IncrementalCommand() {
+
+ @Override
+ public boolean execute() {
+ boolean res = canContinue();
+ if (res) {
+ displayNewFolder();
+ return false;
+ }
+ return true;
+ }
+
+ });
+ }
+
+ private boolean canContinue() {
+ if (groups == null)
+ return false;
+ return true;
+ }
+
+ void displayNewFolder() {
+ RestResource currentFolder = GSS.get().getTreeView().getSelection();
+ if (currentFolder == null) {
+ GSS.get().displayError("You have to select the parent folder first");
+ return;
+ }
+ FolderPropertiesDialog dlg = new FolderPropertiesDialog(images, true, groups);
+ dlg.center();
+ }
+
+ private void getGroups() {
+ GetCommand<GroupsResource> gg = new GetCommand<GroupsResource>(GroupsResource.class, GSS.get().getCurrentUserResource().getGroupsPath(), null){
+
+ @Override
+ public void onComplete() {
+ GroupsResource res = getResult();
+ MultipleGetCommand<GroupResource> ga = new MultipleGetCommand<GroupResource>(GroupResource.class, res.getGroupPaths().toArray(new String[]{}), null){
+
+ @Override
+ public void onComplete() {
+ List<GroupResource> groupList = getResult();
+ groups = groupList;
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch groups");
+ groups = new ArrayList<GroupResource>();
+ }
+
+ @Override
+ public void onError(String p, Throwable throwable) {
+ GWT.log("Path:"+p, throwable);
+ }
+ };
+ DeferredCommand.addCommand(ga);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch groups");
+ groups = new ArrayList<GroupResource>();
+ }
+ };
+ DeferredCommand.addCommand(gg);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.GroupPropertiesDialog;
+
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class NewGroupCommand implements Command{
+ private PopupPanel containerPanel;
+
+ /**
+ * @param _containerPanel
+ */
+ public NewGroupCommand(PopupPanel _containerPanel){
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ displayNewGroup();
+ }
+
+ void displayNewGroup() {
+ GroupPropertiesDialog dlg = new GroupPropertiesDialog(true);
+ dlg.center();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.UserAddDialog;
+
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class NewUserCommand implements Command {
+ private PopupPanel containerPanel;
+
+ /**
+ * @param _containerPanel
+ */
+ public NewUserCommand(PopupPanel _containerPanel){
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ displayNewUser();
+ }
+
+ private void displayNewUser() {
+ UserAddDialog dlg = new UserAddDialog();
+ dlg.center();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.clipboard.Clipboard;
+import org.gss_project.gss.web.client.clipboard.ClipboardItem;
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * @author kman Command for pasting Clipboard contents
+ */
+public class PasteCommand implements Command {
+
+ private PopupPanel containerPanel;
+
+ public PasteCommand(PopupPanel _containerPanel) {
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ Object selection = GSS.get().getCurrentSelection();
+ if(selection != null && selection instanceof GroupResource){
+ final ClipboardItem citem = GSS.get().getClipboard().getItem();
+ GroupResource group = (GroupResource) GSS.get().getCurrentSelection();
+ if(citem.getUser() != null){
+ PostCommand cg = new PostCommand(group.getUri()+"?name="+citem.getUser().getUsername(), "", 201){
+
+ @Override
+ public void onComplete() {
+ GSS.get().getGroups().updateGroups();
+ GSS.get().showUserList();
+ GSS.get().getClipboard().setItem(null);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("User does not exist");
+ else if(statusCode == 409)
+ GSS.get().displayError("A user with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to add user:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error adding user:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cg);
+ return;
+ }
+ }
+ FolderResource selectedFolder = null;
+ if(selection != null && selection instanceof RestResourceWrapper)
+ selectedFolder = ((RestResourceWrapper)selection).getResource();
+ //TODO:CELLTREE
+ /*
+ else if(GSS.get().getFolders().getCurrent() != null && ((DnDTreeItem)GSS.get().getFolders().getCurrent()).getFolderResource() != null)
+ selectedFolder = ((DnDTreeItem)GSS.get().getFolders().getCurrent()).getFolderResource();
+ */
+ if (selectedFolder != null) {
+ final ClipboardItem citem = GSS.get().getClipboard().getItem();
+ if (citem != null && citem.getRestResourceWrapper() != null) {
+ String target = selectedFolder.getUri();
+ target = target.endsWith("/") ? target : target + '/';
+ target = target + URL.encodeComponent(citem.getRestResourceWrapper().getResource().getName());
+ if (citem.getOperation() == Clipboard.COPY) {
+ PostCommand cf = new PostCommand(citem.getRestResourceWrapper().getUri() + "?copy=" + target, "", 200) {
+
+ @Override
+ public void onComplete() {
+ //TODO:CELLTREE
+ //GSS.get().getFolders().updateFolder((DnDTreeItem) GSS.get().getFolders().getCurrent());
+ GSS.get().getTreeView().updateNodeChildren(GSS.get().getTreeView().getSelection());
+ GSS.get().getStatusPanel().updateStats();
+ GSS.get().getClipboard().setItem(null);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+
+ else if(statusCode == 409)
+ GSS.get().displayError("A folder with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to copy folder:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error copying folder:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cf);
+ } else if (citem.getOperation() == Clipboard.CUT) {
+ PostCommand cf = new PostCommand(citem.getRestResourceWrapper().getUri() + "?move=" + target, "", 200) {
+
+ @Override
+ public void onComplete() {
+ //TODO:CELLTREE
+ /*
+ List<TreeItem> items = GSS.get().getFolders().getItemsOfTreeForPath(citem.getFolderResource().getUri());
+ for (TreeItem item : items)
+ if (item.getParentItem() != null && !item.equals(GSS.get().getFolders().getCurrent()))
+ GSS.get().getFolders().updateFolder((DnDTreeItem) item.getParentItem());
+ GSS.get().getFolders().updateFolder((DnDTreeItem) GSS.get().getFolders().getCurrent());
+ */
+ GSS.get().getTreeView().updateNodeChildren(GSS.get().getTreeView().getSelection());
+ GSS.get().getTreeView().updateNodeChildrenForRemove(citem.getRestResourceWrapper().getResource().getParentURI());
+ GSS.get().getStatusPanel().updateStats();
+ GSS.get().getClipboard().setItem(null);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 409)
+ GSS.get().displayError("A folder with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to move folder:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error moving folder:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cf);
+ }
+ return;
+ } else if (citem != null && citem.getFile() != null) {
+ String target = selectedFolder.getUri();
+ target = target.endsWith("/") ? target : target + '/';
+ target = target + URL.encodeComponent(citem.getFile().getName());
+ if (citem.getOperation() == Clipboard.COPY) {
+ PostCommand cf = new PostCommand(citem.getFile().getUri() + "?copy=" + target, "", 200) {
+
+ @Override
+ public void onComplete() {
+ GSS.get().showFileList(true);
+ GSS.get().getStatusPanel().updateStats();
+ GSS.get().getClipboard().setItem(null);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("File not found");
+ else if(statusCode == 409)
+ GSS.get().displayError("A file with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to copy file:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error copying file:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cf);
+ } else if (citem.getOperation() == Clipboard.CUT) {
+ PostCommand cf = new PostCommand(citem.getFile().getUri() + "?move=" + target, "", 200) {
+
+ @Override
+ public void onComplete() {
+ GSS.get().showFileList(true);
+ GSS.get().getStatusPanel().updateStats();
+ GSS.get().getClipboard().setItem(null);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("File not found");
+ else if(statusCode == 409)
+ GSS.get().displayError("A file with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to copy file:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error copying file:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cf);
+ }
+ return;
+ } else if (citem != null && citem.getFiles() != null) {
+ List<FileResource> res = citem.getFiles();
+ List<String> fileIds = new ArrayList<String>();
+ String target = selectedFolder.getUri();
+ target = target.endsWith("/") ? target : target + '/';
+
+ if (citem.getOperation() == Clipboard.COPY) {
+ for (FileResource fileResource : res) {
+ String fileTarget = target + fileResource.getName();
+ fileIds.add(fileResource.getUri() + "?copy=" + fileTarget);
+ }
+ int index = 0;
+ executeCopyOrMove(index, fileIds);
+
+ } else if (citem.getOperation() == Clipboard.CUT) {
+ for (FileResource fileResource : res) {
+ String fileTarget = target + fileResource.getName();
+ fileIds.add(fileResource.getUri() + "?move=" + fileTarget);
+ }
+ int index = 0;
+ executeCopyOrMove(index, fileIds);
+ }
+ return;
+ }
+ }
+ }
+
+ private void executeCopyOrMove(final int index, final List<String> paths){
+ if(index >= paths.size()){
+ GSS.get().showFileList(true);
+ GSS.get().getStatusPanel().updateStats();
+ GSS.get().getClipboard().setItem(null);
+ return;
+ }
+ PostCommand cf = new PostCommand(paths.get(index), "", 200) {
+
+ @Override
+ public void onComplete() {
+ executeCopyOrMove(index+1, paths);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("File not found");
+ else if(statusCode == 409)
+ GSS.get().displayError("A file with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to copy file:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error copying file:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(cf);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.FileMenu;
+import org.gss_project.gss.web.client.FilePropertiesDialog;
+import org.gss_project.gss.web.client.FilesPropertiesDialog;
+import org.gss_project.gss.web.client.FolderPropertiesDialog;
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.FileMenu.Images;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.HeadCommand;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand;
+import org.gss_project.gss.web.client.rest.MultipleHeadCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand.Cached;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupsResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * The command that displays the appropriate Properties dialog, according to the
+ * selected object in the application.
+ *
+ * @author kman
+ */
+public class PropertiesCommand implements Command {
+
+ final FileMenu.Images newImages;
+
+ private PopupPanel containerPanel;
+
+ private List<GroupResource> groups = null;
+
+ private List<FileResource> versions = null;
+
+ private int tabToShow = 0;
+
+ private String userName;
+
+ /**
+ * @param _containerPanel
+ * @param _newImages the images of all the possible delete dialogs
+ * @param _tab the tab to switch to
+ */
+ public PropertiesCommand(PopupPanel _containerPanel, final FileMenu.Images _newImages, int _tab) {
+ containerPanel = _containerPanel;
+ newImages = _newImages;
+ tabToShow = _tab;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ if (GSS.get().getCurrentSelection() instanceof RestResourceWrapper) {
+ GetCommand<FolderResource> eg = new GetCommand<FolderResource>(FolderResource.class, ((RestResourceWrapper) GSS.get().getCurrentSelection()).getUri(),((RestResourceWrapper) GSS.get().getCurrentSelection()).getResource()) {
+
+ @Override
+ public void onComplete() {
+ ((RestResourceWrapper) GSS.get().getCurrentSelection()).setResource(getResult());
+ initialize();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+
+ }
+
+ };
+ DeferredCommand.addCommand(eg);
+ }
+ else if (GSS.get().getCurrentSelection() instanceof FileResource) {
+ final String path = ((FileResource) GSS.get().getCurrentSelection()).getUri();
+ // Needed because firefox caches head requests.
+ HeadCommand<FileResource> eg = new HeadCommand<FileResource>(FileResource.class, path+"?"+Math.random(), null ) {
+
+ @Override
+ public void onComplete() {
+ FileResource res = getResult();
+ GSS.get().setCurrentSelection(res);
+ initialize();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ if(t instanceof RestException)
+ GSS.get().displayError("Unable to retrieve file details:"+((RestException)t).getHttpStatusText());
+ }
+
+ };
+ DeferredCommand.addCommand(eg);
+ }
+ else if (GSS.get().getCurrentSelection() instanceof List) {
+ List<String> paths = new ArrayList<String>();
+ for (FileResource fr : (List<FileResource>) GSS.get().getCurrentSelection())
+ paths.add(fr.getUri()+"?"+Math.random());
+ Cached[] cached = new Cached[paths.size()];
+ int i=0;
+ for (FileResource fr : (List<FileResource>) GSS.get().getCurrentSelection()){
+ Cached c = new Cached();
+ c.uri=fr.getUri()+"?"+Math.random();
+ c.cache=fr;
+ cached[i]=c;
+ i++;
+ }
+ MultipleHeadCommand<FileResource> gv = new MultipleHeadCommand<FileResource>(FileResource.class, paths.toArray(new String[] {}),cached) {
+
+ @Override
+ public void onComplete() {
+ List<FileResource> res = getResult();
+ GSS.get().setCurrentSelection(res);
+ FilesPropertiesDialog dlg = new FilesPropertiesDialog(res);
+ dlg.selectTab(tabToShow);
+ dlg.center();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch files details");
+ }
+
+ @Override
+ public void onError(String p, Throwable throwable) {
+ GWT.log("Path:" + p, throwable);
+ }
+ };
+ DeferredCommand.addCommand(gv);
+ }
+ }
+
+ private void initialize(){
+ getGroups();
+ getVersions();
+ getOwnerFullName();
+ DeferredCommand.addCommand(new IncrementalCommand() {
+
+ @Override
+ public boolean execute() {
+ boolean res = canContinue();
+ if (res) {
+ displayProperties(newImages, GSS.get().findUserFullName(userName));
+ return false;
+ }
+ return true;
+ }
+
+ });
+
+ }
+
+ private boolean canContinue() {
+ String userFullNameFromMap = GSS.get().findUserFullName(userName);
+ if(groups == null || versions == null || userFullNameFromMap == null)
+ return false;
+ return true;
+ }
+
+ /**
+ * Display the appropriate Properties dialog, according to the selected
+ * object in the application.
+ *
+ * @param propImages the images of all the possible properties dialogs
+ */
+ void displayProperties(final Images propImages, final String _userName) {
+ if (GSS.get().getCurrentSelection() instanceof RestResourceWrapper) {
+ FolderPropertiesDialog dlg = new FolderPropertiesDialog(propImages, false, groups);
+ dlg.selectTab(tabToShow);
+ dlg.center();
+ } else if (GSS.get().getCurrentSelection() instanceof FileResource) {
+ FilePropertiesDialog dlg = new FilePropertiesDialog(propImages, groups, versions, _userName);
+ dlg.selectTab(tabToShow);
+ dlg.center();
+ }
+ }
+
+ private void getGroups() {
+ GetCommand<GroupsResource> gg = new GetCommand<GroupsResource>(GroupsResource.class, GSS.get().getCurrentUserResource().getGroupsPath(), null) {
+
+ @Override
+ public void onComplete() {
+ GroupsResource res = getResult();
+ MultipleGetCommand<GroupResource> ga = new MultipleGetCommand<GroupResource>(GroupResource.class, res.getGroupPaths().toArray(new String[] {}), null) {
+
+ @Override
+ public void onComplete() {
+ List<GroupResource> groupList = getResult();
+ groups = groupList;
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch groups");
+ groups = new ArrayList<GroupResource>();
+ }
+
+ @Override
+ public void onError(String p, Throwable throwable) {
+ GWT.log("Path:" + p, throwable);
+ }
+ };
+ DeferredCommand.addCommand(ga);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch groups");
+ groups = new ArrayList<GroupResource>();
+ }
+ };
+ DeferredCommand.addCommand(gg);
+ }
+
+ private void getVersions() {
+ if (GSS.get().getCurrentSelection() instanceof FileResource) {
+ FileResource afile = (FileResource) GSS.get().getCurrentSelection();
+ GWT.log("File is versioned:" + afile.isVersioned(), null);
+ if (afile.isVersioned()) {
+ List<String> paths = new ArrayList<String>();
+ for (int i = 1; i <= afile.getVersion(); i++)
+ paths.add(afile.getUri() + "?version=" + i);
+ MultipleHeadCommand<FileResource> gv = new MultipleHeadCommand<FileResource>(FileResource.class, paths.toArray(new String[] {}), null) {
+
+ @Override
+ public void onComplete() {
+ versions = getResult();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ GSS.get().displayError("Unable to fetch versions");
+ versions = new ArrayList<FileResource>();
+ }
+
+ @Override
+ public void onError(String p, Throwable throwable) {
+ GWT.log("Path:" + p, throwable);
+ }
+ };
+ DeferredCommand.addCommand(gv);
+ } else
+ versions = new ArrayList<FileResource>();
+ } else
+ versions = new ArrayList<FileResource>();
+ }
+
+ private void getOwnerFullName() {
+ if(GSS.get().getCurrentSelection() instanceof FileResource){
+ FileResource fileResource = (FileResource) GSS.get().getCurrentSelection();
+ userName = fileResource.getOwner();
+ if(GSS.get().findUserFullName(userName) == null){
+ GetUserCommand gu = new GetUserCommand(userName);
+ gu.execute();
+ }
+ }else{
+ FolderResource resource = ((RestResourceWrapper) GSS.get().getCurrentSelection()).getResource();
+ userName = resource.getOwner();
+ if(GSS.get().findUserFullName(userName) == null){
+ GetUserCommand gu = new GetUserCommand(userName);
+ gu.execute();
+ }
+ }
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.FileMenu;
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+
+import java.util.List;
+
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class RefreshCommand implements Command {
+
+ final FileMenu.Images newImages;
+
+ private PopupPanel containerPanel;
+
+ /**
+ * @param _containerPanel
+ * @param _newImages the images of all the possible delete dialogs
+ */
+ public RefreshCommand(PopupPanel _containerPanel, final FileMenu.Images _newImages) {
+ containerPanel = _containerPanel;
+ newImages = _newImages;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ if (GSS.get().getCurrentSelection() instanceof FileResource || GSS.get().getCurrentSelection() instanceof List)
+ GSS.get().showFileList(true);
+ else if (GSS.get().getCurrentSelection() instanceof GroupUserResource)
+ return;
+ else{
+ //TODO:CELLTREE
+ //DnDTreeItem selectedTreeItem = (DnDTreeItem) GSS.get().getFolders().getCurrent();
+ //if(selectedTreeItem != null){
+ //GSS.get().getFolders().updateFolder(selectedTreeItem);
+ GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());
+ GSS.get().showFileList(true);
+ //}
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ * @author kman
+ *
+ */
+public class ResreshOthersSharesCommand implements Command{
+ private PopupPanel containerPanel;
+
+ public ResreshOthersSharesCommand(PopupPanel _containerPanel){
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ //TODO:CELLTREE
+ //GSS.get().getFolders().update( GSS.get().getFolders().getCurrent());
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.MultiplePostCommand;
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.TrashFolderResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+
+/**
+ *
+ * Restore trashed files and folders.
+ *
+ * @author kman
+ */
+public class RestoreTrashCommand implements Command{
+ private PopupPanel containerPanel;
+
+ public RestoreTrashCommand(PopupPanel _containerPanel){
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ Object selection = GSS.get().getCurrentSelection();
+ if (selection == null){
+ // Check to see if Trash Node is selected.
+ List folderList = new ArrayList();
+ TrashResource trashItem = GSS.get().getTreeView().getTrash();
+ for(int i=0 ; i < trashItem.getFolders().size() ; i++)
+ folderList.add(trashItem.getFolders().get(i));
+ return;
+ }
+ GWT.log("selection: " + selection.toString(), null);
+ if (selection instanceof FileResource) {
+ final FileResource resource = (FileResource)selection;
+ PostCommand rt = new PostCommand(resource.getUri()+"?restore=","", 200){
+
+ @Override
+ public void onComplete() {
+ //TODO:CELLTREE
+ //GSS.get().getFolders().update(GSS.get().getFolders().getTrashItem());
+
+ GSS.get().showFileList(true);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("File does not exist");
+ else if(statusCode == 409)
+ GSS.get().displayError("A file with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to restore file:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error restoring file:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(rt);
+ }
+ else if (selection instanceof List) {
+ final List<FileResource> fdtos = (List<FileResource>) selection;
+ final List<String> fileIds = new ArrayList<String>();
+ for(FileResource f : fdtos)
+ fileIds.add(f.getUri()+"?restore=");
+ MultiplePostCommand rt = new MultiplePostCommand(fileIds.toArray(new String[0]), 200){
+
+ @Override
+ public void onComplete() {
+ //TODO:CELLTREE
+ //GSS.get().getFolders().update(GSS.get().getFolders().getTrashItem());
+ GSS.get().showFileList(true);
+ }
+
+ @Override
+ public void onError(String p, Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("File does not exist");
+ else if(statusCode == 409)
+ GSS.get().displayError("A file with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to restore file::"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error restoring file:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(rt);
+ }
+ else if (selection instanceof TrashFolderResource) {
+ final FolderResource resource = ((TrashFolderResource)selection).getResource();
+ PostCommand rt = new PostCommand(resource.getUri()+"?restore=","", 200){
+
+ @Override
+ public void onComplete() {
+ //TODO:CELLTREE
+ /*
+ GSS.get().getFolders().updateFolder((DnDTreeItem) GSS.get().getFolders().getRootItem());
+
+ GSS.get().getFolders().update(GSS.get().getFolders().getTrashItem());
+ */
+
+ GSS.get().getTreeView().updateTrashNode();
+ GSS.get().getTreeView().updateRootNode();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("Folder does not exist");
+ else if(statusCode == 409)
+ GSS.get().displayError("A folder with the same name already exists");
+ else if(statusCode == 413)
+ GSS.get().displayError("Your quota has been exceeded");
+ else
+ GSS.get().displayError("Unable to restore folder::"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error restoring folder:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(rt);
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.MultiplePostCommand;
+import org.gss_project.gss.web.client.rest.PostCommand;
+import org.gss_project.gss.web.client.rest.RestException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ *
+ * Move file or folder to trash.
+ *
+ * @author kman
+ *
+ */
+public class ToTrashCommand implements Command{
+ private PopupPanel containerPanel;
+
+ public ToTrashCommand(PopupPanel _containerPanel){
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+ Object selection = GSS.get().getCurrentSelection();
+ if (selection == null)
+ return;
+ GWT.log("selection: " + selection.toString(), null);
+ if (selection instanceof RestResourceWrapper) {
+ FolderResource fdto = ((RestResourceWrapper) selection).getResource();
+ PostCommand tot = new PostCommand(fdto.getUri()+"?trash=","",200){
+
+ @Override
+ public void onComplete() {
+ //TODO:CELLTREE
+ /*
+ TreeItem folder = GSS.get().getFolders().getCurrent();
+ if(folder.getParentItem() != null){
+ GSS.get().getFolders().select(folder.getParentItem());
+ GSS.get().getFolders().updateFolder((DnDTreeItem) folder.getParentItem());
+ }
+ GSS.get().getFolders().update(GSS.get().getFolders().getTrashItem());
+ */
+ FolderResource fres = ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource();
+ GSS.get().getTreeView().updateNodeChildrenForRemove(fres.getParentURI());
+ GSS.get().getTreeView().clearSelection();
+ //GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getTrash());
+ GSS.get().getTreeView().updateTrashNode();
+ GSS.get().showFileList(true);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("Folder does not exist");
+ else
+ GSS.get().displayError("Unable to trash folder:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error trashing folder:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(tot);
+ } else if (selection instanceof FileResource) {
+ FileResource fdto = (FileResource) selection;
+ PostCommand tot = new PostCommand(fdto.getUri()+"?trash=","",200){
+
+ @Override
+ public void onComplete() {
+ GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("File does not exist");
+ else
+ GSS.get().displayError("Unable to trash file:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error trashing file:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(tot);
+
+ }
+ else if (selection instanceof List) {
+ List<FileResource> fdtos = (List<FileResource>) selection;
+ final List<String> fileIds = new ArrayList<String>();
+ for(FileResource f : fdtos)
+ fileIds.add(f.getUri()+"?trash=");
+ MultiplePostCommand tot = new MultiplePostCommand(fileIds.toArray(new String[0]),200){
+
+ @Override
+ public void onComplete() {
+ GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());
+ }
+
+ @Override
+ public void onError(String p, Throwable t) {
+ GWT.log("", t);
+ if(t instanceof RestException){
+ int statusCode = ((RestException)t).getHttpStatusCode();
+ if(statusCode == 405)
+ GSS.get().displayError("You don't have the necessary permissions");
+ else if(statusCode == 404)
+ GSS.get().displayError("File does not exist");
+ else
+ GSS.get().displayError("Unable to trash file:"+((RestException)t).getHttpStatusText());
+ }
+ else
+ GSS.get().displayError("System error trashing file:"+t.getMessage());
+ }
+ };
+ DeferredCommand.addCommand(tot);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2008, 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.FileUploadDialog;
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.GetCommand;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.RestResourceWrapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
+import com.google.gwt.user.client.ui.PopupPanel;
+
+/**
+ * Upload a file command
+ *
+ * @author kman
+ */
+public class UploadFileCommand implements Command {
+
+ private PopupPanel containerPanel;
+ private List<FileResource> files;
+
+ public UploadFileCommand(PopupPanel _containerPanel) {
+ containerPanel = _containerPanel;
+ }
+
+ @Override
+ public void execute() {
+ if(containerPanel!=null)
+ containerPanel.hide();
+ displayNewFile();
+ }
+
+ /**
+ * Display the 'new file' dialog for uploading a new file to the system.
+ */
+ private void displayNewFile() {
+ RestResource currentFolder = GSS.get().getTreeView().getSelection();
+ if (currentFolder == null) {
+ GSS.get().displayError("You have to select the parent folder first");
+ return;
+ }
+ getFileList();
+ DeferredCommand.addCommand(new IncrementalCommand() {
+
+ @Override
+ public boolean execute() {
+ boolean res = canContinue();
+ if (res) {
+ FileUploadDialog dlg = GWT.create(FileUploadDialog.class);
+ dlg.setFiles(files);
+ dlg.center();
+ return false;
+ }
+ return true;
+ }
+
+ });
+ }
+
+ private boolean canContinue() {
+ if (files != null )
+ return true;
+ return false;
+ }
+
+ private void getFileList() {
+ GetCommand<FolderResource> eg = new GetCommand<FolderResource>(FolderResource.class,((RestResourceWrapper)GSS.get().getTreeView().getSelection()).getUri(), null){
+
+ @Override
+ public void onComplete() {
+ files = getResult().getFiles();
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ files = new ArrayList<FileResource>();
+ }
+
+ };
+ DeferredCommand.addCommand(eg);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.commands;
+
+import org.gss_project.gss.web.client.FileMenu;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.ErrorEvent;
+import com.google.gwt.event.dom.client.ErrorHandler;
+import com.google.gwt.event.dom.client.LoadEvent;
+import com.google.gwt.event.dom.client.LoadHandler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.Image;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+
+
+public class ViewImageCommand implements Command {
+
+ final FileMenu.Images newImages;
+
+ private PopupPanel containerPanel;
+
+ private String imageDownloadURL;
+
+ private Label errorLabel = new Label();
+
+ /**
+ * @param _containerPanel
+ * @param _newImages the images of all the possible delete dialogs
+ */
+ public ViewImageCommand(PopupPanel _containerPanel, final FileMenu.Images _newImages, String _imageDownloadURL) {
+ containerPanel = _containerPanel;
+ newImages = _newImages;
+ imageDownloadURL = _imageDownloadURL;
+ }
+
+ @Override
+ public void execute() {
+ containerPanel.hide();
+
+ final Image image = new Image();
+ // Hook up a load handler, so that we can be informed if the image
+ // fails to load.
+ image.addLoadHandler(new LoadHandler() {
+
+ @Override
+ public void onLoad(LoadEvent event) {
+ errorLabel.setText("");
+ }
+ });
+ image.addErrorHandler(new ErrorHandler() {
+
+ @Override
+ public void onError(ErrorEvent event) {
+ errorLabel.setText("An error occurred while loading.");
+ }
+ });
+ image.setUrl(imageDownloadURL);
+ final DialogBox imagePopup = new DialogBox(true, true);
+ imagePopup.setAnimationEnabled(true);
+ imagePopup.setText("Showing image in actual size");
+ VerticalPanel imageViewPanel = new VerticalPanel();
+ errorLabel.setText("loading image...");
+ imageViewPanel.add(errorLabel);
+ imageViewPanel.add(image);
+ imagePopup.setWidget(imageViewPanel);
+ image.setTitle("Click to close");
+ image.addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ imagePopup.hide();
+ }
+ });
+ imagePopup.setPopupPosition(0, 0);
+ imagePopup.show();
+ }
+}
--- /dev/null
+package org.gss_project.gss.web.client.components;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.FocusWidget;
+import com.google.gwt.user.client.ui.HasValue;
+
+/**
+ * Checkbox with three states (checked, unchecked and undefined).
+ *
+ */
+public class TristateCheckBox extends FocusWidget implements HasValue<Boolean> {
+
+ private static final String UNCHECKED_IMG = "images/tristate_unchecked.gif";
+
+ private static final String UNKNOWN_IMG = "images/tristate_intermediate.gif";
+
+ private static final String CHECKED_IMG = "images/tristate_checked.gif";
+
+ private final Element buttonElement = DOM.createElement("input");
+
+ private boolean valueChangeHandlerInitialized;
+
+ private Boolean value;
+
+ private Boolean initialValue;
+
+ public TristateCheckBox(final Boolean state) {
+ DOM.setElementProperty(buttonElement, "type", "image");
+ setElement(buttonElement);
+ setStyleName("tristateCheckbox");
+ DOM.setElementAttribute(buttonElement, "src", UNCHECKED_IMG);
+
+ addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ final String img = DOM.getElementAttribute(buttonElement, "src");
+ String newImg;
+ if (img.endsWith(UNCHECKED_IMG))
+ newImg = CHECKED_IMG;
+ else if (img.endsWith(UNKNOWN_IMG))
+ newImg = UNCHECKED_IMG;
+ else if (img.endsWith(CHECKED_IMG))
+ if (initialValue==null) // Only show unknown choice if there is a reason for it
+ newImg = UNKNOWN_IMG;
+ else
+ newImg = UNCHECKED_IMG;
+ else
+ throw new IllegalArgumentException("unknown checkbox state");
+
+ DOM.setElementAttribute(buttonElement, "src", newImg);
+ }
+
+ });
+
+ setState(state);
+ initialValue = state;
+ }
+
+ public void setState(final Boolean state) {
+ DOM.setElementAttribute(buttonElement, "src", state == null ?
+ UNKNOWN_IMG : state.booleanValue() ? CHECKED_IMG : UNCHECKED_IMG);
+ }
+
+ public Boolean getState() {
+ final String img = DOM.getElementAttribute(buttonElement, "src");
+ if (img.endsWith(UNCHECKED_IMG))
+ return Boolean.FALSE;
+ else if (img.endsWith(UNKNOWN_IMG))
+ return null;
+ else if (img.endsWith(CHECKED_IMG))
+ return Boolean.TRUE;
+ else
+ throw new IllegalArgumentException("unknown checkbox state");
+ }
+
+ @Override
+ public Boolean getValue() {
+ return value;
+ }
+
+ @Override
+ public void setValue(final Boolean _value) {
+ value = _value;
+ }
+
+ @Override
+ public HandlerRegistration addValueChangeHandler(
+ ValueChangeHandler<Boolean> handler) {
+ // Is this the first value change handler? If so, time to add handlers
+ if (!valueChangeHandlerInitialized) {
+ ensureDomEventHandlers();
+ valueChangeHandlerInitialized = true;
+ }
+ return addHandler(handler, ValueChangeEvent.getType());
+ }
+
+ protected void ensureDomEventHandlers() {
+ addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ ValueChangeEvent.fire(TristateCheckBox.this, getValue());
+ }
+ });
+ }
+
+ @Override
+ public void setValue(Boolean _value, boolean fireEvents) {
+ Boolean oldValue = getValue();
+ setValue(_value);
+ if (_value.equals(oldValue))
+ return;
+ if (fireEvents)
+ ValueChangeEvent.fire(this, _value);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+
+
+/**
+ * @author kman
+ *
+ */
+public class CallbackList<T> implements AsyncCallback<T>{
+ List<T> result = new ArrayList();
+ boolean erroneous = false;
+
+ @Override
+ public void onFailure(Throwable arg0) {
+ GWT.log("Error in callback list", arg0);
+ erroneous = true;
+
+ }
+
+
+ @Override
+ public void onSuccess(T arg0) {
+ result.add(arg0);
+ }
+
+
+
+ /**
+ * Retrieve the result.
+ *
+ * @return the result
+ */
+ public List<T> getResult() {
+ return result;
+ }
+
+
+
+ /**
+ * Retrieve the erroneous.
+ *
+ * @return the erroneous
+ */
+ public boolean isErroneous() {
+ return erroneous;
+ }
+
+
+
+
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.InsufficientPermissionsException;
+
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.Response;
+
+/**
+ * @author kman
+ *
+ */
+public abstract class DeleteCommand extends RestCommand{
+
+ boolean complete = false;
+
+ public DeleteCommand(String pathToDelete){
+ this(pathToDelete, true);
+ }
+
+
+ public DeleteCommand(String pathToDelete, boolean showLoading){
+ setShowLoadingIndicator(showLoading);
+ if(isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Deleting ",pathToDelete);
+ final String path;
+ if(pathToDelete.endsWith("/"))
+ path = pathToDelete;
+ else
+ path = pathToDelete+"/";
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.DELETE, path);
+
+ try {
+ handleHeaders(builder, path);
+ builder.sendRequest("", new RequestCallback() {
+
+ @Override
+ public void onError(Request arg0, Throwable arg1) {
+ complete = true;
+ DeleteCommand.this.onError(arg1);
+ }
+
+ @Override
+ public void onResponseReceived(Request arg0, Response arg1) {
+ complete=true;
+ if(arg1.getStatusCode() == 204)
+ onComplete();
+ else if(arg1.getStatusCode() == 403)
+ sessionExpired();
+ else if(arg1.getStatusCode() == 405)
+ DeleteCommand.this.onError(new InsufficientPermissionsException("You don't have permissions to delete this resource"));
+ else
+ DeleteCommand.this.onError(new RestException(path, arg1.getStatusCode(), arg1.getStatusText(), arg1.getText()));
+ }
+
+ });
+ } catch (Exception ex) {
+ complete=true;
+ onError(ex);
+ }
+ }
+
+ public boolean isComplete() {
+ return complete;
+ }
+
+ @Override
+ public boolean execute() {
+ boolean com = isComplete();
+ if(com){
+ if(isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ return false;
+ }
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+import org.gss_project.gss.web.client.rest.resource.GroupsResource;
+import org.gss_project.gss.web.client.rest.resource.OtherUserResource;
+import org.gss_project.gss.web.client.rest.resource.OthersResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.SearchResource;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TagsResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import org.gss_project.gss.web.client.rest.resource.UploadStatusResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+import org.gss_project.gss.web.client.rest.resource.UserSearchResource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.http.client.Response;
+
+/**
+ * @author kman
+ */
+public abstract class GetCommand<T extends RestResource> extends RestCommand{
+
+ boolean complete = false;
+ T result = null;
+ Throwable exception = null;
+ Class<T> aclass;
+ private final String path;
+ private String username;
+ private boolean requestSent = false;
+ T cached;
+
+ private static final long MAX_CACHE_AGE = 1000;
+
+ private static class RequestData {
+ public String path;
+ public String username;
+
+ public RequestData(String _path, String _username) {
+ path = _path;
+ username = _username;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((path == null) ? 0 : path.hashCode());
+ result = prime * result + ((username == null) ? 0 : username.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RequestData other = (RequestData) obj;
+ if (path == null) {
+ if (other.path != null)
+ return false;
+ } else if (!path.equals(other.path))
+ return false;
+ if (username == null) {
+ if (other.username != null)
+ return false;
+ } else if (!username.equals(other.username))
+ return false;
+ return true;
+ }
+ }
+
+ private static class ResponseData {
+ public long timestamp;
+ public Object result;
+ public ResponseData(long _timestamp, Object _result) {
+ timestamp = _timestamp;
+ result = _result;
+ }
+ }
+
+ private static Map<RequestData, ResponseData> cache = new HashMap<RequestData, ResponseData>();
+
+
+ public GetCommand(Class<T> theclass, String pathToGet, T theCached){
+ this(theclass, pathToGet, true, theCached);
+ }
+
+ public GetCommand(Class<T> theclass, String pathToGet, boolean showLoading, T theCached){
+ setShowLoadingIndicator(showLoading);
+ if(isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Getting ",pathToGet);
+ this.aclass = theclass;
+ if(pathToGet.indexOf("?") != -1)
+ path = pathToGet;
+ else
+ path =fixPath(pathToGet);
+ this.cached = theCached;
+ }
+
+ public GetCommand(Class<T> theclass, String aUsername , String pathToGet, T theCached){
+ this(theclass, aUsername, pathToGet, true, theCached);
+ }
+
+ public GetCommand(Class<T> theclass, String aUsername , String pathToGet, boolean showLoading, T theCached){
+ setShowLoadingIndicator(showLoading);
+ if(isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Getting ",pathToGet);
+ this.aclass = theclass;
+ path = fixPath(pathToGet);
+ this.username = aUsername;
+ this.cached = theCached;
+ }
+
+ private void sendRequest(){
+ if(requestSent)
+ return;
+ requestSent=true;
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
+ if(cached!=null && cached.getLastModifiedSince() != null)
+ builder.setHeader("If-Modified-Since", cached.getLastModifiedSince());
+ try {
+ if(username == null)
+ handleHeaders(builder, path);
+ else
+ handleHeaders(username, builder, path);
+ builder.sendRequest("", new RestCallback(path) {
+
+ @Override
+ public Object deserialize(Response response) {
+ return deserializeResponse(path, response);
+ }
+
+ @Override
+ public void handleError(Request request, Throwable _exception) {
+ result = null;
+ complete = true;
+ exception = _exception;
+ if(_exception instanceof RestException)
+ if(((RestException)_exception).getHttpStatusCode() == 304 && cached != null){
+ GWT.log("Using cache:"+cached.getUri(), null);
+ handleSuccess(cached);
+ return;
+ }
+
+ }
+
+ @Override
+ public void handleSuccess(Object object) {
+ result = (T) object;
+ complete = true;
+ }
+
+ });
+ } catch (Exception ex) {
+ complete = true;
+ exception = ex;
+ }
+ }
+ public boolean isComplete() {
+ return complete;
+ }
+
+ public T getResult(){
+ return result;
+ }
+
+ @Override
+ public boolean execute() {
+ boolean com = isComplete();
+ RequestData key = new RequestData(path, username);
+ if (!com) {
+ if (cache.containsKey(key)) {
+ ResponseData resp = cache.get(key);
+ if (resp==null) {
+ return true;
+ }
+
+ // Cache hit
+ if (System.currentTimeMillis()-resp.timestamp>MAX_CACHE_AGE) {
+ // Cache stale, remove
+ cache.put(key,null);
+ }
+ else {
+ // Use cache data
+ if(isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ if (resp.result instanceof Throwable) {
+ // Error to be handled
+ Throwable ex = (Throwable) resp.result;
+ onError(ex);
+ return false;
+ }
+ result = (T) resp.result;
+ if (result != null) {
+ onComplete();
+ }
+ complete = true;
+ return false;
+ }
+ }
+
+ if(!requestSent) {
+ cache.put(key,null);
+ sendRequest();
+ }
+ }
+
+ if(com){
+ if(isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ if(getResult() != null) {
+ // Add to cache
+ cache.put(key, new ResponseData(System.currentTimeMillis(), getResult()));
+ onComplete();
+ }
+ else {
+ cache.put(key, new ResponseData(System.currentTimeMillis(), exception));
+ onError(exception);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public Object deserializeResponse(String aPath, Response response) {
+ RestResource result1 = null;
+ if(aclass.equals(FolderResource.class)){
+ result1 = new FolderResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(FileResource.class)){
+ result1 = new FileResource(aPath);
+ result1.createFromJSON(response.getHeader("X-GSS-Metadata"));
+ }
+ else if(aclass.equals(GroupsResource.class)){
+ result1 = new GroupsResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(TrashResource.class)){
+ result1 = new TrashResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(SharedResource.class)){
+ result1 = new SharedResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(OthersResource.class)){
+ result1 = new OthersResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(OtherUserResource.class)){
+ result1 = new OtherUserResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(GroupResource.class)){
+ result1 = new GroupResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(GroupUserResource.class)){
+ result1 = new GroupUserResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(UserResource.class)){
+ result1 = new UserResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(TagsResource.class)){
+ result1 = new TagsResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(SearchResource.class)){
+ result1 = new SearchResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(UserSearchResource.class)){
+ result1 = new UserSearchResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(UploadStatusResource.class)){
+ result1 = new UploadStatusResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ return result1;
+ }
+
+ public T getCached() {
+ return cached;
+ }
+
+ public void setCached(T theCached) {
+ this.cached = theCached;
+ }
+
+ public boolean usedCachedVersion(){
+ if(exception !=null && exception instanceof RestException)
+ if(((RestException)exception).getHttpStatusCode() == 304){
+ return true;
+ }
+ return false;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.ObjectNotFoundException;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+import org.gss_project.gss.web.client.rest.resource.GroupsResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.http.client.Response;
+
+
+/**
+ * @author kman
+ *
+ */
+public abstract class HeadCommand<T extends RestResource> extends RestCommand{
+
+ boolean complete = false;
+ T result = null;
+ Class<T> aclass;
+ private boolean requestSent = false;
+ T cached;
+ final String path;
+
+ public HeadCommand(Class<T> theclass, String pathToGet, T theCached){
+ this(theclass, pathToGet, true, theCached);
+ }
+
+ public HeadCommand(Class<T> theClass, String pathToGet, boolean showLoading, T theCached){
+ setShowLoadingIndicator(showLoading);
+ this.aclass = theClass;
+ if(isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Getting ",pathToGet);
+
+ if(theClass.equals(FileResource.class))
+ path = pathToGet;
+ else
+ path = fixPath(pathToGet);
+ this.cached = theCached;
+
+ }
+
+ private void sendRequest(){
+ if(requestSent)
+ return;
+ requestSent=true;
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.HEAD, path);
+ if(cached!=null && cached.getLastModifiedSince() != null){
+ GWT.log("ADDING IF MODIFIED HEADERS", null);
+ builder.setHeader("If-Modified-Since", cached.getLastModifiedSince());
+ }
+ try {
+ handleHeaders(builder, path);
+ builder.sendRequest("", new RestCallback(path) {
+
+ @Override
+ public Object deserialize(Response response) {
+ return deserializeResponse(path, response);
+ }
+
+ @Override
+ public void handleError(Request request, Throwable exception) {
+ if(exception instanceof RestException)
+ if(((RestException)exception).getHttpStatusCode() == 304 && cached != null){
+ GWT.log("Using cache:"+cached.getUri(), null);
+ handleSuccess(cached);
+ return;
+ }
+ complete = true;
+ HeadCommand.this.onError(exception);
+ }
+
+ @Override
+ public void handleSuccess(Object object) {
+ result = (T) object;
+ complete = true;
+ }
+
+ });
+ } catch (Exception ex) {
+ complete = true;
+ onError(ex);
+ }
+ }
+
+ public boolean isComplete() {
+ return complete;
+ }
+
+ public T getResult(){
+ return result;
+ }
+
+ @Override
+ public boolean execute() {
+ if(!requestSent)
+ sendRequest();
+ boolean com = isComplete();
+ if(com){
+ if(isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ if(getResult() != null)
+ onComplete();
+ else
+ onError(new ObjectNotFoundException("Resource Not Found"));
+ return false;
+ }
+ return true;
+ }
+
+ public Object deserializeResponse(String aPath, Response response){
+ RestResource result1 = null;
+ if(aclass.equals(FolderResource.class)){
+ result1 = new FolderResource(aPath);
+ result1.createFromJSON(response.getText());
+
+ }
+ else if(aclass.equals(FileResource.class)){
+ result1 = new FileResource(aPath);
+ result1.createFromJSON(response.getHeader("X-GSS-Metadata"));
+ }
+ else if(aclass.equals(GroupsResource.class)){
+ result1 = new GroupsResource(aPath);
+ result1.createFromJSON(response.getText());
+ }
+ else if(aclass.equals(TrashResource.class)){
+ result1 = new TrashResource(aPath);
+ result1.createFromJSON(response.getText());
+
+ }
+ else if(aclass.equals(SharedResource.class)){
+ result1 = new SharedResource(aPath);
+ result1.createFromJSON(response.getText());
+
+ }
+ else if(aclass.equals(GroupResource.class)){
+ result1 = new GroupResource(aPath);
+ result1.createFromJSON(response.getText());
+
+ }
+ else if(aclass.equals(GroupUserResource.class)){
+ result1 = new GroupUserResource(aPath);
+ result1.createFromJSON(response.getText());
+
+ }
+ else if(aclass.equals(UserResource.class)){
+ result1 = new UserResource(aPath);
+ result1.createFromJSON(response.getText());
+
+ }
+ return result1;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.InsufficientPermissionsException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.Response;
+
+/**
+ * @author kman
+ */
+public abstract class MultipleDeleteCommand extends RestCommand {
+
+
+ Map<String, Throwable> errors = new HashMap<String, Throwable>();
+
+ List<String> successPaths = new ArrayList<String>();
+
+ String[] paths;
+
+ public MultipleDeleteCommand(String[] pathToDelete){
+ this(pathToDelete, true);
+ }
+
+ public MultipleDeleteCommand(String[] pathToDelete, boolean showLoading){
+ setShowLoadingIndicator(showLoading);
+ if(isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Deleting "+pathToDelete.length+" items",null);
+ paths = pathToDelete;
+ for (final String pathg : pathToDelete) {
+ GWT.log("[DEL]"+pathg, null);
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.DELETE, pathg);
+
+ try {
+ handleHeaders(builder, pathg);
+ builder.sendRequest("", new RequestCallback() {
+
+ @Override
+ public void onError(Request arg0, Throwable arg1) {
+ errors.put(pathg, arg1);
+ }
+
+ @Override
+ public void onResponseReceived(Request arg0, Response arg1) {
+ if (arg1.getStatusCode() == 204)
+ successPaths.add(pathg);
+ else if(arg1.getStatusCode() == 403)
+ sessionExpired();
+ else if (arg1.getStatusCode() == 405)
+ errors.put(pathg, new InsufficientPermissionsException("You don't have permissions to delete this resource"));
+ else
+ errors.put(pathg, new RestException(pathg, arg1.getStatusCode(), arg1.getStatusText(), arg1.getText()));
+ }
+
+ });
+ } catch (Exception ex) {
+ errors.put(pathg, ex);
+ }
+ }
+ }
+
+ public boolean isComplete() {
+ return errors.size() + successPaths.size() == paths.length;
+ }
+
+ @Override
+ public boolean execute() {
+ boolean com = isComplete();
+ if (com) {
+ if(hasErrors())
+ for(String p : errors.keySet())
+ onError(p, errors.get(p));
+ onComplete();
+ if(isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ return false;
+ }
+ return true;
+ }
+
+ public boolean hasErrors(){
+ return errors.size() >0;
+ }
+
+
+ /**
+ * Retrieve the errors.
+ *
+ * @return the errors
+ */
+ public Map<String, Throwable> getErrors() {
+ return errors;
+ }
+
+ public void debug(){
+ GWT.log("-ERRORS-->"+getErrors().size(), null);
+ for(String p : getErrors().keySet())
+ GWT.log("error:"+p, getErrors().get(p));
+ }
+
+ public abstract void onError(String path, Throwable throwable);
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+import org.gss_project.gss.web.client.rest.resource.GroupsResource;
+import org.gss_project.gss.web.client.rest.resource.OtherUserResource;
+import org.gss_project.gss.web.client.rest.resource.OthersResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.Response;
+import com.google.gwt.user.client.DeferredCommand;
+
+/**
+ * @author kman
+ */
+public abstract class MultipleGetCommand<T extends RestResource> extends RestCommand {
+
+ Class<T> aclass;
+ List<T> result = new ArrayList<T>();
+ Map<String, Throwable> errors = new HashMap<String, Throwable>();
+ Cached[] cached;
+ String[] paths;
+ private boolean requestSent=false;
+
+ public MultipleGetCommand(Class<T> aNewClass, String[] pathToGet, Cached[] theCached) {
+ this(aNewClass, pathToGet, true, theCached);
+ }
+
+ public MultipleGetCommand(Class<T> aNewClass, String[] pathToGet, boolean showLoading, Cached[] theCached) {
+ setShowLoadingIndicator(showLoading);
+ if (isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Getting "+pathToGet.length+" items", null);
+ aclass = aNewClass;
+ paths = pathToGet;
+ this.cached = theCached;
+ //sendRequest();
+ }
+
+ private void sendRequest() {
+ if (requestSent)
+ return;
+ requestSent=true;
+ if (cached!=null)
+ for (final Cached pathg : cached)
+ DeferredCommand.addCommand(new GetCommand<T>(aclass,pathg.uri,false,(T)pathg.cache) {
+
+ @Override
+ public void onComplete() {
+ MultipleGetCommand.this.result.add(getResult());
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ errors.put(pathg.uri, t);
+ }
+
+ });
+ else
+ for (final String pathg : paths)
+ DeferredCommand.addCommand(new GetCommand<T>(aclass,pathg,false,null) {
+
+ @Override
+ public void onComplete() {
+ MultipleGetCommand.this.result.add(getResult());
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ errors.put(pathg, t);
+ }
+
+ });
+ }
+
+ public boolean isComplete() {
+ return result.size()+errors.size() == paths.length;
+ }
+
+ public List<T> getResult() {
+ if (aclass.equals(FolderResource.class))
+ Collections.sort(result, new Comparator() {
+ @Override
+ public int compare(Object o1, Object o2) {
+ return ((FolderResource)o1).getName().compareTo(((FolderResource)o2).getName());
+ }
+
+ });
+ else if(aclass.equals(GroupResource.class))
+ Collections.sort(result, new Comparator() {
+ @Override
+ public int compare(Object o1, Object o2) {
+ return ((GroupResource)o1).getName().compareTo(((GroupResource)o2).getName());
+ }
+
+ });
+ else if(aclass.equals(GroupUserResource.class))
+ Collections.sort(result, new Comparator() {
+ @Override
+ public int compare(Object o1, Object o2) {
+ return ((GroupUserResource)o1).getName().compareTo(((GroupUserResource)o2).getName());
+ }
+
+ });
+ return result;
+ }
+
+ @Override
+ public boolean execute() {
+ if (!requestSent)
+ sendRequest();
+ boolean com = isComplete();
+ if (com) {
+ if (isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ if (hasErrors())
+ for(String p : errors.keySet())
+ onError(p, errors.get(p));
+ onComplete();
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @param p
+ * @param throwable
+ */
+ public abstract void onError(String p, Throwable throwable);
+
+ public Object deserializeResponse(String path, Response response) {
+ RestResource result1 = null;
+ if (aclass.equals(FolderResource.class)) {
+ result1 = new FolderResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ else if (aclass.equals(FileResource.class)){
+ result1 = new FileResource(path);
+ result1.createFromJSON(response.getHeader("X-GSS-Metadata"));
+ }
+ else if (aclass.equals(GroupsResource.class)) {
+ result1 = new GroupsResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ else if (aclass.equals(TrashResource.class)) {
+ result1 = new TrashResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ else if (aclass.equals(SharedResource.class)) {
+ result1 = new SharedResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ else if (aclass.equals(OthersResource.class)) {
+ result1 = new OthersResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ else if (aclass.equals(OtherUserResource.class)) {
+ result1 = new OtherUserResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ else if (aclass.equals(GroupResource.class)) {
+ result1 = new GroupResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ else if (aclass.equals(GroupUserResource.class)) {
+ result1 = new GroupUserResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ else if (aclass.equals(UserResource.class)) {
+ result1 = new UserResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ return result1;
+ }
+
+ public boolean hasErrors() {
+ return errors.size() >0;
+ }
+
+ /**
+ * Retrieve the errors.
+ *
+ * @return the errors
+ */
+ public Map<String, Throwable> getErrors() {
+ return errors;
+ }
+
+ protected void debug() {
+ GWT.log("--->"+result.size(), null);
+ GWT.log("-ERRORS-->"+getErrors().size(), null);
+ for(String p : getErrors().keySet())
+ GWT.log("error:"+p, getErrors().get(p));
+ }
+
+ public static class Cached {
+ public String uri;
+ public RestResource cache;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand.Cached;
+import org.gss_project.gss.web.client.rest.resource.FileResource;
+import org.gss_project.gss.web.client.rest.resource.FolderResource;
+import org.gss_project.gss.web.client.rest.resource.GroupResource;
+import org.gss_project.gss.web.client.rest.resource.GroupUserResource;
+import org.gss_project.gss.web.client.rest.resource.GroupsResource;
+import org.gss_project.gss.web.client.rest.resource.RestResource;
+import org.gss_project.gss.web.client.rest.resource.SharedResource;
+import org.gss_project.gss.web.client.rest.resource.TrashResource;
+import org.gss_project.gss.web.client.rest.resource.UserResource;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.Response;
+import com.google.gwt.user.client.DeferredCommand;
+
+
+/**
+ * @author kman
+ *
+ */
+public abstract class MultipleHeadCommand <T extends RestResource> extends RestCommand {
+ String[] paths;
+ Class<T> aclass;
+ List<T> result = new ArrayList<T>();
+ Map<String, Throwable> errors = new HashMap<String, Throwable>();
+ private boolean requestSent=false;
+ Cached[] cached;
+
+ public MultipleHeadCommand(Class<T> theClass, String[] pathToGet, Cached[] theCached) {
+ this(theClass, pathToGet, true, theCached);
+ }
+
+ public MultipleHeadCommand(Class<T> theClass, String[] pathToGet, boolean showLoading, Cached[] theCached) {
+ setShowLoadingIndicator(showLoading);
+ if(isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Getting "+pathToGet.length+" items", null);
+ paths = pathToGet;
+ this.aclass = theClass;
+ this.cached = theCached;
+ //sendRequest();
+ }
+
+ private void sendRequest() {
+ if(requestSent)
+ return;
+ requestSent=true;
+ if(cached!=null)
+ for (final Cached c : cached){
+ final String path;
+ if(aclass.equals(FileResource.class)){
+ if(c.uri.indexOf("?") == -1)
+ path=c.uri+"?"+Math.random();
+ else
+ path=c.uri;
+ }
+ else
+ path = fixPath(c.uri);
+ DeferredCommand.addCommand(new HeadCommand<T>(aclass,path,false, (T)c.cache) {
+
+ @Override
+ public void onComplete() {
+ MultipleHeadCommand.this.result.add(getResult());
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ errors.put(path, t);
+ }
+
+ });
+ }
+ else
+ for (String pathg : paths) {
+ final String path;
+ if(aclass.equals(FileResource.class))
+ path = pathg;
+ else
+ path = fixPath(pathg);
+ DeferredCommand.addCommand(new HeadCommand<T>(aclass,path,false, null) {
+ @Override
+ public void onComplete() {
+ MultipleHeadCommand.this.result.add(getResult());
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ errors.put(path, t);
+ }
+ });
+ }
+ }
+ public boolean isComplete() {
+ return result.size()+errors.size() == paths.length;
+ }
+
+ public List<T> getResult() {
+ return result;
+ }
+
+ @Override
+ public boolean execute() {
+ if(!requestSent)
+ sendRequest();
+ boolean com = isComplete();
+ if (com) {
+ if(isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ if(hasErrors())
+ for(String p : errors.keySet())
+ onError(p, errors.get(p));
+ onComplete();
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @param p
+ * @param throwable
+ */
+ public abstract void onError(String p, Throwable throwable);
+
+ public Object deserializeResponse(String path, Response response) {
+ RestResource result1 = null;
+ if (aclass.equals(FolderResource.class)) {
+ result1 = new FolderResource(path);
+ result1.createFromJSON(response.getText());
+ } else if (aclass.equals(FileResource.class)) {
+ result1 = new FileResource(path);
+ result1.createFromJSON(response.getHeader("X-GSS-Metadata"));
+ } else if (aclass.equals(GroupsResource.class)) {
+ result1 = new GroupsResource(path);
+ result1.createFromJSON(response.getText());
+ } else if (aclass.equals(TrashResource.class)) {
+ result1 = new TrashResource(path);
+ result1.createFromJSON(response.getText());
+ } else if (aclass.equals(SharedResource.class)) {
+ result1 = new SharedResource(path);
+ result1.createFromJSON(response.getText());
+ } else if (aclass.equals(GroupResource.class)) {
+ result1 = new GroupResource(path);
+ result1.createFromJSON(response.getText());
+ } else if (aclass.equals(GroupUserResource.class)) {
+ result1 = new GroupUserResource(path);
+ result1.createFromJSON(response.getText());
+ } else if (aclass.equals(UserResource.class)) {
+ result1 = new UserResource(path);
+ result1.createFromJSON(response.getText());
+ }
+ return result1;
+ }
+
+ public boolean hasErrors(){
+ return errors.size() >0;
+ }
+
+ /**
+ * Retrieve the errors.
+ *
+ * @return the errors
+ */
+ public Map<String, Throwable> getErrors() {
+ return errors;
+ }
+
+ public void debug(){
+ GWT.log("--->"+result.size(), null);
+ GWT.log("-ERRORS-->"+getErrors().size(), null);
+ for(String p : getErrors().keySet())
+ GWT.log("error:"+p, getErrors().get(p));
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.InsufficientPermissionsException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.Response;
+
+
+/**
+ * @author kman
+ *
+ */
+public abstract class MultiplePostCommand extends RestCommand {
+
+
+ Map<String, Throwable> errors = new HashMap<String, Throwable>();
+
+ List<String> successPaths = new ArrayList<String>();
+
+ String[] paths;
+
+ public MultiplePostCommand(String[] pathToDelete, final int okStatusCode){
+ this(pathToDelete, okStatusCode, true);
+ }
+
+ public MultiplePostCommand(String[] pathToDelete, String data, final int okStatusCode){
+ this(pathToDelete, data, okStatusCode, true);
+ }
+
+ public MultiplePostCommand(String[] pathToDelete, final int okStatusCode, boolean showLoading){
+ this(pathToDelete, "", okStatusCode, showLoading);
+ }
+
+ public MultiplePostCommand(String[] pathToDelete, String data, final int okStatusCode, boolean showLoading){
+ setShowLoadingIndicator(showLoading);
+ if(isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Updating "+pathToDelete.length+" items", null);
+ paths = pathToDelete;
+ for (final String pathg : pathToDelete) {
+ GWT.log("[DEL]"+pathg, null);
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, pathg);
+
+ try {
+ handleHeaders(builder, pathg);
+ builder.sendRequest(data, new RequestCallback() {
+
+ @Override
+ public void onError(Request arg0, Throwable arg1) {
+ errors.put(pathg, arg1);
+ }
+
+ @Override
+ public void onResponseReceived(Request arg0, Response arg1) {
+ if (arg1.getStatusCode() == okStatusCode)
+ successPaths.add(pathg);
+ else if(arg1.getStatusCode() == 403)
+ sessionExpired();
+ else if (arg1.getStatusCode() == 405)
+ errors.put(pathg, new InsufficientPermissionsException("You don't have permissions to delete this resource"));
+ else
+ errors.put(pathg, new RestException(pathg, arg1.getStatusCode(), arg1.getStatusText(), arg1.getText()));
+ }
+
+ });
+ } catch (Exception ex) {
+ errors.put(pathg, ex);
+ }
+ }
+ }
+
+ public boolean isComplete() {
+ return errors.size() + successPaths.size() == paths.length;
+ }
+
+ @Override
+ public boolean execute() {
+ boolean com = isComplete();
+ if (com) {
+ if(hasErrors())
+ for(String p : errors.keySet())
+ onError(p, errors.get(p));
+ onComplete();
+ if(isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * @param p
+ * @param throwable
+ */
+ public abstract void onError(String p, Throwable throwable);
+
+ public boolean hasErrors(){
+ return errors.size() >0;
+ }
+
+
+ /**
+ * Retrieve the errors.
+ *
+ * @return the errors
+ */
+ public Map<String, Throwable> getErrors() {
+ return errors;
+ }
+
+ public void debug(){
+ GWT.log("-ERRORS-->"+getErrors().size(), null);
+ for(String p : getErrors().keySet())
+ GWT.log("error:"+p, getErrors().get(p));
+ }
+
+ @Override
+ public void onError(Throwable t) {
+
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.Response;
+
+
+/**
+ * @author kman
+ *
+ */
+public abstract class PostCommand extends RestCommand{
+ boolean complete = false;
+ String postBody=null;
+
+ public PostCommand(final String path, String data, final int okStatusCode) {
+ this(path, data, okStatusCode, true);
+ }
+
+ public PostCommand(final String path, String data, final int okStatusCode, boolean showLoading) {
+ setShowLoadingIndicator(showLoading);
+ if(isShowLoadingIndicator())
+ GSS.get().showLoadingIndicator("Updating ",path);
+
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, path);
+
+ try {
+ handleHeaders(builder, path);
+ builder.sendRequest(data, new RequestCallback() {
+
+ @Override
+ public void onError(Request arg0, Throwable arg1) {
+ complete = true;
+ PostCommand.this.onError(arg1);
+ }
+
+ @Override
+ public void onResponseReceived(Request req, Response resp) {
+ complete=true;
+ int status = resp.getStatusCode();
+ // Normalize IE status 1223 to a regular 204.
+ if (status == 1223)
+ status = 204;
+
+ if (status == okStatusCode) {
+ postBody = resp.getText();
+ onComplete();
+ } else if (status == 403)
+ sessionExpired();
+ else
+ PostCommand.this.onError(new RestException(path, status, resp.getStatusText(), resp.getText()));
+ }
+
+ });
+ } catch (Exception ex) {
+ complete=true;
+ onError(ex);
+ }
+ }
+
+ public boolean isComplete() {
+ return complete;
+ }
+
+ @Override
+ public boolean execute() {
+ boolean com = isComplete();
+ if (com) {
+ if (isShowLoadingIndicator())
+ GSS.get().hideLoadingIndicator();
+ return false;
+ }
+ return true;
+ }
+
+ public String getPostBody() {
+ return postBody;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.Response;
+
+
+/**
+ * @author kman
+ *
+ */
+public abstract class RestCallback implements RequestCallback {
+
+ private static final int HTTP_OK = 200;
+ private String path;
+ private int okcode = -1;
+
+ public RestCallback(String aPath) {
+ path = aPath;
+ }
+
+ public RestCallback(String aPath, int okCode) {
+ path = aPath;
+ okcode = okCode;
+ }
+
+ @Override
+ public void onError(Request request, Throwable exception) {
+ handleError(request, exception);
+ }
+
+ @Override
+ public void onResponseReceived(Request request, Response response) {
+ try {
+ if (okcode == -1 && response.getStatusCode() == HTTP_OK)
+ handleSuccess(deserialize(response));
+ //this one is only used for trash handling where empty trash has 201 status code
+ else if(okcode !=-1 && (response.getStatusCode() == okcode || response.getStatusCode() == HTTP_OK))
+ handleSuccess(deserialize(response));
+ else if(response.getStatusCode() == 403)
+ RestCommand.sessionExpired();
+ else {
+ String statusText = "";
+ String text = "";
+ // Ignore JavaScript errors caused by non-existent text.
+ try {
+ statusText = response.getStatusText();
+ } catch (Exception e) { }
+ try {
+ text = response.getText();
+ } catch (Exception e) { }
+ handleError(request, new RestException(path, response.getStatusCode(), statusText, text));
+ }
+ } catch (Exception e) {
+ handleError(request,e);
+ }
+ }
+
+ public abstract void handleSuccess(Object object);
+
+ public abstract void handleError(Request request, Throwable exception);
+
+ public abstract Object deserialize(Response response);
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.SessionExpiredDialog;
+
+import com.google.gwt.http.client.RequestBuilder;
+import com.google.gwt.user.client.IncrementalCommand;
+
+/**
+ * @author kman
+ */
+public abstract class RestCommand implements IncrementalCommand {
+ protected boolean showLoadingIndicator = true;
+
+ protected void handleHeaders(String username, RequestBuilder requestBuilder, String path) {
+ String date = getDate();
+ requestBuilder.setHeader("X-GSS-Date", date);
+
+ GSS app = GSS.get();
+ String token = app.getToken();
+ if (token == null)
+ token = "aa";
+ String resource = path.substring(app.getApiPath().length()-1,path.length());
+ String sig = calculateSig(requestBuilder.getHTTPMethod(), date, resource, base64decode(token));
+ requestBuilder.setHeader("Authorization", username + " " + sig);
+ requestBuilder.setHeader("Accept", "application/json; charset=utf-8");
+ }
+
+ protected void handleHeaders(RequestBuilder requestBuilder, String path) {
+ if (GSS.get().getCurrentUserResource() != null) {
+ String username = GSS.get().getCurrentUserResource().getUsername();
+ handleHeaders(username, requestBuilder, path);
+ } else
+ GSS.get().displayError("no username");
+ }
+
+ public static native String getDate()/*-{
+ return (new Date()).toUTCString();
+ }-*/;
+
+ public static native String getDate(Long ms)/*-{
+ return (new Date(ms)).toUTCString();
+ }-*/;
+
+ public static native String calculateSig(String method, String date, String resource, String token)/*-{
+ $wnd.b64pad = "=";
+ var q = resource.indexOf('?');
+ var res = q == -1? resource: resource.substring(0, q);
+ var data = method + date + res;
+ var sig = $wnd.b64_hmac_sha1(token, data);
+ return sig;
+ }-*/;
+
+ public static native String base64decode(String encStr)/*-{
+ if (typeof atob === 'function') {
+ return atob(encStr);
+ }
+ var base64s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var bits;
+ var decOut = "";
+ var i = 0;
+ for(; i<encStr.length; i += 4){
+ bits = (base64s.indexOf(encStr.charAt(i)) & 0xff) <<18 | (base64s.indexOf(encStr.charAt(i +1)) & 0xff) <<12 | (base64s.indexOf(encStr.charAt(i +2)) & 0xff) << 6 | base64s.indexOf(encStr.charAt(i +3)) & 0xff;
+ decOut += String.fromCharCode((bits & 0xff0000) >>16, (bits & 0xff00) >>8, bits & 0xff);
+ }
+ if(encStr.charCodeAt(i -2) == 61){
+ return(decOut.substring(0, decOut.length -2));
+ }
+ else if(encStr.charCodeAt(i -1) == 61){
+ return(decOut.substring(0, decOut.length -1));
+ }
+ else {
+ return(decOut);
+ }
+ }-*/;
+
+ public void onComplete() {}
+
+ public abstract void onError(Throwable t);
+
+ public String fixPath(String pathToFix) {
+ if(pathToFix.endsWith("/"))
+ return pathToFix;
+ return pathToFix+"/";
+ }
+
+ /**
+ * Retrieve the showLoadingIndicator.
+ *
+ * @return the showLoadingIndicator
+ */
+ public boolean isShowLoadingIndicator() {
+ return showLoadingIndicator;
+ }
+
+ /**
+ * Modify the showLoadingIndicator.
+ *
+ * @param newShowLoadingIndicator the showLoadingIndicator to set
+ */
+ public void setShowLoadingIndicator(boolean newShowLoadingIndicator) {
+ showLoadingIndicator = newShowLoadingIndicator;
+ }
+
+ static void sessionExpired() {
+ SessionExpiredDialog dlg = new SessionExpiredDialog();
+ dlg.center();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+
+/**
+ * @author kman
+ *
+ */
+public class RestException extends Throwable {
+
+ private int httpStatusCode;
+ private String httpStatusText;
+ private String text;
+
+ public RestException() {
+ }
+
+ public RestException(String message) {
+ super(message);
+ }
+
+ public RestException(Throwable innerException) {
+ super(innerException);
+ }
+
+ public RestException(String message, Throwable innerException) {
+ super(message, innerException);
+ }
+
+ public RestException(String aPath, int aStatusCode, String aStatusText, String aText) {
+ super("HTTP error: " + aStatusCode+"\nPapth:"+aPath + "\nStatus text:" + aStatusText + "\nText:" + aText);
+ httpStatusCode = aStatusCode;
+ httpStatusText = aStatusText;
+ text = aText;
+ }
+
+ public int getHttpStatusCode() {
+ return httpStatusCode;
+ }
+
+ public String getHttpStatusText() {
+ return httpStatusText;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest;
+
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.Response;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * @author kman
+ */
+public abstract class RestGetCallback implements RequestCallback {
+
+ private static final int HTTP_OK = 200;
+
+ private AsyncCallback callback;
+ private String path;
+ private int okcode = -1;
+
+ public RestGetCallback(String aPath, AsyncCallback aCallback) {
+ callback = aCallback;
+ path = aPath;
+ }
+
+ public RestGetCallback(String aPath, AsyncCallback aCallback, int okCode) {
+ callback = aCallback;
+ path = aPath;
+ okcode = okCode;
+ }
+
+ @Override
+ public void onError(Request request, Throwable exception) {
+ callback.onFailure(exception);
+ }
+
+ @Override
+ public void onResponseReceived(Request request, Response response) {
+ try {
+ if (okcode == -1 && response.getStatusCode() == HTTP_OK)
+ callback.onSuccess(deserialize(response));
+ //this one is only used for trash handling where empty trash has 201 status code
+ else if(okcode !=-1 && (response.getStatusCode() == okcode || response.getStatusCode() == HTTP_OK))
+ callback.onSuccess(deserialize(response));
+ else
+ callback.onFailure(new RestException(path, response.getStatusCode(), response.getStatusText(), response.getText()));
+ } catch (Exception e) {
+ callback.onFailure(e);
+ }
+ }
+
+ public abstract Object deserialize(Response response);
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+import com.google.gwt.json.client.JSONString;
+
+/**
+ * @author kman
+ */
+public class FileResource extends RestResource {
+
+ public FileResource(String aUri) {
+ super(aUri);
+ }
+
+ String name;
+
+ String owner;
+
+ String createdBy;
+
+ String modifiedBy;
+
+ Date creationDate;
+
+ Date modificationDate;
+
+ String contentType;
+
+ Long contentLength;
+
+ boolean readForAll;
+
+ boolean versioned;
+
+ Integer version;
+
+ String etag;
+
+ boolean deleted = false;
+
+ List<String> tags = new ArrayList<String>();
+
+ Set<PermissionHolder> permissions = new HashSet<PermissionHolder>();
+
+ String folderURI;
+
+ String path;
+
+ String folderName;
+ Boolean shared;
+
+
+
+
+ /**
+ * Modify the shared.
+ *
+ * @param _shared the shared to set
+ */
+ public void setShared(Boolean _shared) {
+ this.shared = _shared;
+ }
+
+ /**
+ * Retrieve the folderName.
+ *
+ * @return the folderName
+ */
+ public String getFolderName() {
+ return folderName;
+ }
+
+ /**
+ * Modify the folderName.
+ *
+ * @param aFolderName the folderName to set
+ */
+ public void setFolderName(String aFolderName) {
+ folderName = aFolderName;
+ }
+
+ /**
+ * Retrieve the path.
+ *
+ * @return the path
+ */
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * Modify the path.
+ *
+ * @param aPath the path to set
+ */
+ public void setPath(String aPath) {
+ path = aPath;
+ }
+
+ /**
+ * Retrieve the name.
+ *
+ * @return the name
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Modify the name.
+ *
+ * @param aName the name to set
+ */
+ public void setName(String aName) {
+ name = aName;
+ }
+
+ /**
+ * Retrieve the owner.
+ *
+ * @return the owner
+ */
+ public String getOwner() {
+ return owner;
+ }
+
+ /**
+ * Modify the owner.
+ *
+ * @param newOwner the owner to set
+ */
+ public void setOwner(String newOwner) {
+ owner = newOwner;
+ }
+
+ /**
+ * Retrieve the createdBy.
+ *
+ * @return the createdBy
+ */
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ /**
+ * Modify the createdBy.
+ *
+ * @param aCreatedBy the createdBy to set
+ */
+ public void setCreatedBy(String aCreatedBy) {
+ createdBy = aCreatedBy;
+ }
+
+ /**
+ * Retrieve the modifiedBy.
+ *
+ * @return the modifiedBy
+ */
+ public String getModifiedBy() {
+ return modifiedBy;
+ }
+
+ /**
+ * Modify the modifiedBy.
+ *
+ * @param aModifiedBy the modifiedBy to set
+ */
+ public void setModifiedBy(String aModifiedBy) {
+ modifiedBy = aModifiedBy;
+ }
+
+ /**
+ * Retrieve the creationDate.
+ *
+ * @return the creationDate
+ */
+ public Date getCreationDate() {
+ return creationDate;
+ }
+
+ /**
+ * Modify the creationDate.
+ *
+ * @param aCreationDate the creationDate to set
+ */
+ public void setCreationDate(Date aCreationDate) {
+ creationDate = aCreationDate;
+ }
+
+ /**
+ * Retrieve the modificationDate.
+ *
+ * @return the modificationDate
+ */
+ public Date getModificationDate() {
+ return modificationDate;
+ }
+
+ /**
+ * Modify the modificationDate.
+ *
+ * @param aModificationDate the modificationDate to set
+ */
+ public void setModificationDate(Date aModificationDate) {
+ modificationDate = aModificationDate;
+ }
+
+ /**
+ * Retrieve the contentType.
+ *
+ * @return the contentType
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+ /**
+ * Modify the contentType.
+ *
+ * @param newContentType the contentType to set
+ */
+ public void setContentType(String newContentType) {
+ contentType = newContentType;
+ }
+
+ /**
+ * Retrieve the contentLength.
+ *
+ * @return the contentLength
+ */
+ public Long getContentLength() {
+ return contentLength;
+ }
+
+ /**
+ * Modify the contentLength.
+ *
+ * @param newContentLength the contentLength to set
+ */
+ public void setContentLength(Long newContentLength) {
+ contentLength = newContentLength;
+ }
+
+ /**
+ * Retrieve the readForAll.
+ *
+ * @return the readForAll
+ */
+ public boolean isReadForAll() {
+ return readForAll;
+ }
+
+ /**
+ * Modify the readForAll.
+ *
+ * @param newReadForAll the readForAll to set
+ */
+ public void setReadForAll(boolean newReadForAll) {
+ readForAll = newReadForAll;
+ }
+
+ /**
+ * Retrieve the versioned.
+ *
+ * @return the versioned
+ */
+ public boolean isVersioned() {
+ return versioned;
+ }
+
+ /**
+ * Modify the versioned.
+ *
+ * @param newVersioned the versioned to set
+ */
+ public void setVersioned(boolean newVersioned) {
+ versioned = newVersioned;
+ }
+
+ /**
+ * Retrieve the version.
+ *
+ * @return the version
+ */
+ public Integer getVersion() {
+ return version;
+ }
+
+ /**
+ * Modify the version.
+ *
+ * @param aVersion the version to set
+ */
+ public void setVersion(Integer aVersion) {
+ version = aVersion;
+ }
+
+ /**
+ * Retrieve the etag.
+ *
+ * @return the etag
+ */
+ public String getEtag() {
+ return etag;
+ }
+
+ /**
+ * Modify the etag.
+ *
+ * @param anEtag the etag to set
+ */
+ public void setEtag(String anEtag) {
+ etag = anEtag;
+ }
+
+ /**
+ * Retrieve the tags.
+ *
+ * @return the tags
+ */
+ public List<String> getTags() {
+ return tags;
+ }
+
+ /**
+ * Modify the tags.
+ *
+ * @param newTags the tags to set
+ */
+ public void setTags(List<String> newTags) {
+ tags = newTags;
+ }
+
+ /**
+ * Retrieve the permissions.
+ *
+ * @return the permissions
+ */
+ public Set<PermissionHolder> getPermissions() {
+ return permissions;
+ }
+
+ /**
+ * Modify the permissions.
+ *
+ * @param newPermissions the permissions to set
+ */
+ public void setPermissions(Set<PermissionHolder> newPermissions) {
+ permissions = newPermissions;
+ }
+
+ /**
+ * Retrieve the deleted.
+ *
+ * @return the deleted
+ */
+ public boolean isDeleted() {
+ return deleted;
+ }
+
+ /**
+ * Modify the deleted.
+ *
+ * @param newDeleted the deleted to set
+ */
+ public void setDeleted(boolean newDeleted) {
+ deleted = newDeleted;
+ }
+
+ /**
+ * Retrieve the folderURI.
+ *
+ * @return the folderURI
+ */
+ public String getFolderURI() {
+ return folderURI;
+ }
+
+ /**
+ * Modify the folderURI.
+ *
+ * @param aFolderURI the folderURI to set
+ */
+ public void setFolderURI(String aFolderURI) {
+ folderURI = aFolderURI;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONObject metadata = (JSONObject) JSONParser.parse(text);
+ name = unmarshallString(metadata, "name");
+ name = URL.decodeComponent(name);
+ path = unmarshallString(metadata, "path");
+ path = URL.decodeComponent(path);
+ owner = unmarshallString(metadata, "owner");
+ contentType = unmarshallString(metadata, "content");
+ readForAll = unmarshallBoolean(metadata, "readForAll");
+ versioned = unmarshallBoolean(metadata, "versioned");
+ createdBy = unmarshallString(metadata, "createdBy");
+ modifiedBy = unmarshallString(metadata, "modifiedBy");
+ setShared(unmarshallBoolean(metadata, "shared"));
+ if (metadata.get("version") != null)
+ version = new Integer(metadata.get("version").toString());
+
+ deleted = unmarshallBoolean(metadata, "deleted");
+ if (deleted)
+ GWT.log("FOUND A DELETED FILE:" + name, null);
+
+ if (metadata.get("folder") != null) {
+ JSONObject folder = metadata.get("folder").isObject();
+ folderURI = unmarshallString(folder, "uri");
+ folderName = unmarshallString(folder, "name");
+ if(folderName != null)
+ folderName = URL.decodeComponent(folderName);
+ }
+
+ if (metadata.get("permissions") != null) {
+ JSONArray perm = metadata.get("permissions").isArray();
+ if (perm != null)
+ for (int i = 0; i < perm.size(); i++) {
+ JSONObject obj = perm.get(i).isObject();
+ if (obj != null) {
+ PermissionHolder permission = new PermissionHolder();
+ if (obj.get("user") != null)
+ permission.setUser(unmarshallString(obj, "user"));
+ if (obj.get("group") != null) {
+ String group = unmarshallString(obj, "group");
+ group = URL.decodeComponent(group);
+ permission.setGroup(group);
+ }
+ permission.setRead(unmarshallBoolean(obj, "read"));
+ permission.setWrite(unmarshallBoolean(obj, "write"));
+ permission.setModifyACL(unmarshallBoolean(obj, "modifyACL"));
+ permissions.add(permission);
+ }
+ }
+
+ }
+ if (metadata.get("tags") != null) {
+ JSONArray perm = metadata.get("tags").isArray();
+ if (perm != null)
+ for (int i = 0; i < perm.size(); i++) {
+ JSONString obj = perm.get(i).isString();
+ if(obj != null)
+ tags.add(URL.decodeComponent(obj.stringValue()));
+ }
+ }
+ if (metadata.get("creationDate") != null)
+ creationDate = new Date(new Long(metadata.get("creationDate").toString()));
+ if (metadata.get("modificationDate") != null)
+ modificationDate = new Date(new Long(metadata.get("modificationDate").toString()));
+ if (metadata.get("size") != null)
+ contentLength = Long.parseLong(metadata.get("size").toString());
+ }
+
+ /**
+ * Return the file size in a humanly readable form, using SI units to denote
+ * size information, e.g. 1 KB = 1000 B (bytes).
+ *
+ * @return the fileSize
+ */
+ public String getFileSizeAsString() {
+ return getFileSizeAsString(contentLength);
+ }
+
+ /**
+ * Return the given size in a humanly readable form, using SI units to denote
+ * size information, e.g. 1 KB = 1000 B (bytes).
+ *
+ * @param size in bytes
+ * @return the size in human readable string
+ */
+ public static String getFileSizeAsString(long size) {
+ if (size < 1024)
+ return String.valueOf(size) + " B";
+ else if (size < 1024 * 1024)
+ return getSize(size, 1024D) + " KB";
+ else if (size < 1024 * 1024 * 1024)
+ return getSize(size, (1024D * 1024D)) + " MB";
+ return getSize(size, (1024D * 1024D * 1024D)) + " GB";
+ }
+
+ private static String getSize(Long size, Double division) {
+ Double res = Double.valueOf(size.toString()) / division;
+ NumberFormat nf = NumberFormat.getFormat("######.#");
+ return nf.format(res);
+ }
+
+ public boolean isShared(){
+ return shared;
+ }
+
+ public boolean isShared(String ownerUser){
+ GWT.log("OWNER USER:"+ownerUser, null);
+ if (isReadForAll())
+ return true;
+ if(permissions != null)
+ for(PermissionHolder perm : permissions){
+ if(perm.getUser() != null && !ownerUser.equals(perm.getUser()))
+ return true;
+ if(perm.getGroup() != null)
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ if(modificationDate != null)
+ return getDate(modificationDate.getTime());
+ return null;
+ }
+}
+
--- /dev/null
+/*
+ * Copyright 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.gss_project.gss.web.client.rest.resource;
+
+import org.gss_project.gss.web.client.DisplayHelper;
+import org.gss_project.gss.web.client.GSS;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand.Cached;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+import com.google.gwt.user.client.ui.TreeItem;
+
+/**
+ * @author kman
+ */
+public class FolderResource extends RestResource {
+
+ public FolderResource(String aUri) {
+ super(aUri);
+ }
+
+ String name;
+
+ String owner;
+
+ String createdBy;
+
+ String modifiedBy;
+
+ Date creationDate;
+
+ Date modificationDate;
+
+ List<String> filePaths = new LinkedList<String>();
+
+ List<String> subfolderPaths = new LinkedList<String>();
+
+ Set<PermissionHolder> permissions = new HashSet<PermissionHolder>();
+
+ List<FolderResource> folders = new ArrayList<FolderResource>();
+
+ List<FileResource> files = new ArrayList<FileResource>();
+
+ String parentURI;
+
+ boolean deleted = false;
+
+ boolean needsExpanding = false;
+
+ String parentName;
+
+ private boolean filesExpanded=false;
+
+ boolean readForAll;
+
+ Boolean shared;
+
+
+
+
+
+ /**
+ * Modify the shared.
+ *
+ * @param shared the shared to set
+ */
+ public void setShared(Boolean shared) {
+ this.shared = shared;
+ }
+
+ /**
+ * Modify the parentName.
+ *
+ * @param aParentName the parentName to set
+ */
+ public void setParentName(String aParentName) {
+ parentName = aParentName;
+ }
+
+ /**
+ * Retrieve the name.
+ *
+ * @return the name
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Modify the name.
+ *
+ * @param aName the name to set
+ */
+ public void setName(String aName) {
+ name = aName;
+ }
+
+ /**
+ * Retrieve the owner.
+ *
+ * @return the owner
+ */
+ public String getOwner() {
+ return owner;
+ }
+
+ /**
+ * Modify the owner.
+ *
+ * @param anOwner the owner to set
+ */
+ public void setOwner(String anOwner) {
+ owner = anOwner;
+ }
+
+ /**
+ * Retrieve the createdBy.
+ *
+ * @return the createdBy
+ */
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ /**
+ * Modify the createdBy.
+ *
+ * @param aCreatedBy the createdBy to set
+ */
+ public void setCreatedBy(String aCreatedBy) {
+ createdBy = aCreatedBy;
+ }
+
+ /**
+ * Retrieve the modifiedBy.
+ *
+ * @return the modifiedBy
+ */
+ public String getModifiedBy() {
+ return modifiedBy;
+ }
+
+ /**
+ * Modify the modifiedBy.
+ *
+ * @param aModifiedBy the modifiedBy to set
+ */
+ public void setModifiedBy(String aModifiedBy) {
+ modifiedBy = aModifiedBy;
+ }
+
+ /**
+ * Retrieve the creationDate.
+ *
+ * @return the creationDate
+ */
+ public Date getCreationDate() {
+ return creationDate;
+ }
+
+ /**
+ * Modify the creationDate.
+ *
+ * @param aCreationDate the creationDate to set
+ */
+ public void setCreationDate(Date aCreationDate) {
+ creationDate = aCreationDate;
+ }
+
+ /**
+ * Retrieve the modificationDate.
+ *
+ * @return the modificationDate
+ */
+ public Date getModificationDate() {
+ return modificationDate;
+ }
+
+ /**
+ * Modify the modificationDate.
+ *
+ * @param aModificationDate the modificationDate to set
+ */
+ public void setModificationDate(Date aModificationDate) {
+ modificationDate = aModificationDate;
+ }
+
+ /**
+ * Retrieve the filePaths.
+ *
+ * @return the filePaths
+ */
+ public List<String> getFilePaths() {
+ return filePaths;
+ }
+
+ /**
+ * Modify the filePaths.
+ *
+ * @param newFilePaths the filePaths to set
+ */
+ public void setFilePaths(List<String> newFilePaths) {
+ filePaths = newFilePaths;
+ }
+
+ /**
+ * Retrieve the subfolderPaths.
+ *
+ * @return the subfolderPaths
+ */
+ public List<String> getSubfolderPaths() {
+ return subfolderPaths;
+ }
+
+ /**
+ * Modify the subfolderPaths.
+ *
+ * @param newSubfolderPaths the subfolderPaths to set
+ */
+ public void setSubfolderPaths(List<String> newSubfolderPaths) {
+ subfolderPaths = newSubfolderPaths;
+ }
+
+ /**
+ * Retrieve the permissions.
+ *
+ * @return the permissions
+ */
+ public Set<PermissionHolder> getPermissions() {
+ return permissions;
+ }
+
+ /**
+ * Modify the permissions.
+ *
+ * @param newPermissions the permissions to set
+ */
+ public void setPermissions(Set<PermissionHolder> newPermissions) {
+ permissions = newPermissions;
+ }
+
+ /**
+ * Retrieve the deleted.
+ *
+ * @return the deleted
+ */
+ public boolean isDeleted() {
+ return deleted;
+ }
+
+ /**
+ * Modify the deleted.
+ *
+ * @param newDeleted the deleted to set
+ */
+ public void setDeleted(boolean newDeleted) {
+ deleted = newDeleted;
+ }
+
+ public void removeSubfolderPath(String spath) {
+ if (subfolderPaths.remove(spath))
+ return;
+ else if (subfolderPaths.remove(spath + "/"))
+ return;
+ else
+ subfolderPaths.remove(spath.substring(0, spath.length() - 1));
+ }
+
+ /**
+ * Retrieve the folders.
+ *
+ * @return the folders
+ */
+ public List<FolderResource> getFolders() {
+ return folders;
+ }
+
+ /**
+ * Modify the folders.
+ *
+ * @param newFolders the folders to set
+ */
+ public void setFolders(List<FolderResource> newFolders) {
+ folders = newFolders;
+ }
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<FileResource> getFiles() {
+ return files;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFiles the files to set
+ */
+ public void setFiles(List<FileResource> newFiles) {
+ files = newFiles;
+ }
+
+ /**
+ * Retrieve the parentURI.
+ *
+ * @return the parentURI
+ */
+ public String getParentURI() {
+ return parentURI;
+ }
+
+ /**
+ * Modify the parentURI.
+ *
+ * @param aParentURI the parentURI to set
+ */
+ public void setParentURI(String aParentURI) {
+ parentURI = aParentURI;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONObject json = (JSONObject) JSONParser.parse(text);
+ name = unmarshallString(json, "name");
+ owner = unmarshallString(json, "owner");
+ createdBy = unmarshallString(json, "createdBy");
+ modifiedBy = unmarshallString(json, "modifiedBy");
+ deleted = unmarshallBoolean(json, "deleted");
+ shared = unmarshallBoolean(json, "shared");
+ readForAll = unmarshallBoolean(json, "readForAll");
+ if (deleted)
+ GWT.log("FOUND A DELETED FOLDER:" + name, null);
+
+ if (json.get("parent") != null) {
+ JSONObject parent = json.get("parent").isObject();
+ parentURI = unmarshallString(parent, "uri");
+ parentName = unmarshallString(parent, "name");
+ }
+
+ if (json.get("permissions") != null) {
+ JSONArray perm = json.get("permissions").isArray();
+ if (perm != null)
+ for (int i = 0; i < perm.size(); i++) {
+ JSONObject obj = perm.get(i).isObject();
+ if (obj != null) {
+ PermissionHolder permission = new PermissionHolder();
+ if (obj.get("user") != null)
+ permission.setUser(unmarshallString(obj, "user"));
+ if (obj.get("group") != null)
+ permission.setGroup(URL.decodeComponent(unmarshallString(obj, "group")));
+ permission.setRead(unmarshallBoolean(obj, "read"));
+ permission.setWrite(unmarshallBoolean(obj, "write"));
+ permission.setModifyACL(unmarshallBoolean(obj, "modifyACL"));
+ permissions.add(permission);
+ }
+ }
+ }
+ if (json.get("folders") != null) {
+ JSONArray subs = json.get("folders").isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject so = subs.get(i).isObject();
+ if (so != null) {
+ String subUri = unmarshallString(so, "uri");
+ String subName = unmarshallString(so, "name");
+ if (subUri != null && subName != null) {
+ if (!subUri.endsWith("/"))
+ subUri = subUri + "/";
+ FolderResource sub = new FolderResource(subUri);
+ sub.setName(subName);
+ sub.setParentURI(uri);
+ sub.setParentName(name);
+ sub.setNeedsExpanding(true);
+ folders.add(sub);
+ subfolderPaths.add(subUri);
+ }
+ }
+ }
+ }
+ if (json.get("files") != null) {
+ JSONArray subs = json.get("files").isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject fo = subs.get(i).isObject();
+ if (fo != null) {
+ String fname = unmarshallString(fo, "name");
+ String fowner = unmarshallString(fo, "owner");
+ String fcontent = unmarshallString(fo, "content");
+ String fpath = unmarshallString(fo, "path");
+ Boolean fshared = unmarshallBoolean(fo, "shared");
+ fpath = URL.decodeComponent(fpath);
+ Integer fversion = null;
+ if (fo.get("version") != null)
+ fversion = new Integer(fo.get("version").toString());
+ boolean fdeleted = unmarshallBoolean(fo, "deleted");
+ Date fcreationDate = null;
+ if (fo.get("creationDate") != null)
+ fcreationDate = new Date(new Long(fo.get("creationDate").toString()));
+ Date fmodificationDate = null;
+ if (fo.get("modificationDate") != null)
+ fmodificationDate = new Date(new Long(fo.get("modificationDate").toString()));
+ String furi = unmarshallString(fo, "uri");
+ Long fsize = 0L;
+ if (fo.get("size") != null)
+ fsize = new Long(fo.get("size").toString());
+ filePaths.add(furi);
+ FileResource fs = new FileResource(furi);
+ fs.setName(fname);
+ fs.setOwner(fowner);
+ fs.setPath(fpath);
+ fs.setVersioned(unmarshallBoolean(fo, "versioned"));
+ fs.setVersion(fversion);
+ fs.setContentLength(fsize);
+ fs.setDeleted(fdeleted);
+ fs.setShared(fshared);
+ fs.setCreationDate(fcreationDate);
+ fs.setModificationDate(fmodificationDate);
+ fs.setContentType(fcontent);
+ files.add(fs);
+ }
+ }
+ }
+ if (json.get("creationDate") != null)
+ creationDate = new Date(new Long(json.get("creationDate").toString()));
+ if (json.get("modificationDate") != null)
+ modificationDate = new Date(new Long(json.get("modificationDate").toString()));
+ }
+
+ public String getParentName(){
+ return parentName;
+ }
+
+ /**
+ * Retrieve the needsExpanding.
+ *
+ * @return the needsExpanding
+ */
+ public boolean isNeedsExpanding() {
+ return needsExpanding;
+ }
+
+ /**
+ * Modify the needsExpanding.
+ *
+ * @param newNeedsExpanding the needsExpanding to set
+ */
+ public void setNeedsExpanding(boolean newNeedsExpanding) {
+ needsExpanding = newNeedsExpanding;
+ }
+
+ public boolean isShared(){
+ return shared;
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ if(modificationDate != null)
+ return getDate(modificationDate.getTime());
+ return null;
+ }
+
+ public MultipleGetCommand.Cached[] getCache(){
+ if(getSubfolderPaths().size() != getFolders().size()){
+ GWT.log("MISMATCH IN PATH AND FOLDERS SIZE", null);
+ return null;
+ }
+ MultipleGetCommand.Cached[] result = new MultipleGetCommand.Cached[getSubfolderPaths().size()];
+ for(int i=0; i<getFolders().size();i++){
+ FolderResource r = getFolders().get(i);
+ Cached c = new Cached();
+ c.cache=r;
+ c.uri=r.uri;
+ result[i] = c;
+ }
+ return result;
+ }
+
+ public MultipleGetCommand.Cached[] getFileCache(){
+ if(getFilePaths().size() != getFiles().size()){
+ GWT.log("MISMATCH IN PATH AND FILES SIZE", null);
+ return null;
+ }
+ if(!filesExpanded)
+ return null;
+ MultipleGetCommand.Cached[] result = new MultipleGetCommand.Cached[getFilePaths().size()];
+ for(int i=0; i<getFiles().size();i++){
+ FileResource r = getFiles().get(i);
+ Cached c = new Cached();
+ c.cache=r;
+ c.uri=r.uri;
+ result[i] = c;
+ }
+ return result;
+ }
+
+ public void setFilesExpanded(boolean newFilesExpanded) {
+ filesExpanded = newFilesExpanded;
+ }
+ /**
+ * this method constructs the partial path of a given TreeItem using it's text
+ *
+ * @param selectedItem the selectedItem to check
+ */
+ private String constructPartialPath(TreeItem selectedItem){
+ String result = DisplayHelper.trim(selectedItem.getText());
+ TreeItem parent = selectedItem.getParentItem();
+ while (!(DisplayHelper.trim(parent.getText()).equals("My Shared") || DisplayHelper.trim(parent.getText()).equals("Other's Shared")||DisplayHelper.trim(parent.getText()).equals("Trash"))){
+ result = DisplayHelper.trim(parent.getText()) + "/" + result;
+ if(result.equals("My Shared")||result.equals("Other's Shared")) return result;
+ parent = parent.getParentItem();
+ }
+
+ return result;
+ }
+ /**
+ * examine whether a folder name like "Trash", "My Shared", "Other's Shared" is inside path
+ *
+ * @param selectedItem the selectedTreeItem to check
+ */
+
+ private boolean containsFolder(TreeItem selectedItem, String folderName){
+ TreeItem parent = selectedItem.getParentItem();
+ while (parent != null){
+ String parentItemText = parent.getText();
+ String parentItemTextTr = DisplayHelper.trim(parentItemText);
+ if(parentItemTextTr.equals(folderName)) return true;
+ parent = parent.getParentItem();
+ }
+ return false;
+ }
+ @Override
+ public String constructUri(TreeItem treeItem, String path){
+ String constructedUri = "";
+ if(containsFolder(treeItem, "My Shared")){
+ //case: selected folders below My Shared folder
+ String partialUri = constructPartialPath(treeItem);
+ constructedUri = constructedUri + "Files/shared/" + partialUri;
+ return constructedUri;
+ }else if(containsFolder(treeItem, "Other's Shared")){
+ //case: selected folders below Other's Shared folder
+ String partialPath = constructPartialPath(treeItem);
+ constructedUri = constructedUri + "Files/others/"+ partialPath;
+ return constructedUri;
+ }
+ else if(getParentURI()==null){
+ if(containsFolder(treeItem, "Trash")){
+ //case: selected folders below Trash folder
+ String partialUri = constructPartialPath(treeItem);
+ constructedUri = constructedUri + "Files/trash/" + partialUri;
+ return constructedUri;
+ }
+ //case: home folder is selected
+ constructedUri = constructedUri + "Files/files/" + getName();
+ return constructedUri;
+ }
+ else if(treeItem.getParentItem() == null){
+ //this is the case when the user uses the browser's forward arrow to navigate through other's
+ //shared folders and item.getParentItem is null only inside other's shared folder
+ String apiPath = GSS.get().getApiPath();
+ String newPath = getParentURI().substring(apiPath.lastIndexOf("/"));
+ constructedUri = constructedUri + "Files"+ newPath + getName();
+ return constructedUri;
+ }
+ else{
+ String finalUri = getParentURI().substring(path.lastIndexOf("/")) + getName();
+ constructedUri = constructedUri + "Files"+ finalUri;
+ return constructedUri;
+ }
+
+ }
+
+ /**
+ * Retrieve the readForAll.
+ *
+ * @return the readForAll
+ */
+ public boolean isReadForAll() {
+ return readForAll;
+ }
+ /**
+ * Modify the readForAll.
+ *
+ * @param newReadForAll the readForAll to set
+ */
+ public void setReadForAll(boolean newReadForAll) {
+ readForAll = newReadForAll;
+ }
+
+
+ public int countNotDeletedSubfolders(){
+ int count=0;
+ for(FolderResource r : folders){
+ if(!r.isDeleted())
+ count++;
+ }
+ return count;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.http.client.URL;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONParser;
+
+/**
+ * @author kman
+ */
+public class GroupResource extends RestResource {
+
+ public GroupResource(String aUri) {
+ super(aUri);
+ }
+
+ List<String> userPaths = new ArrayList<String>();
+
+ /**
+ * Retrieve the userPaths.
+ *
+ * @return the userPaths
+ */
+ public List<String> getUserPaths() {
+ return userPaths;
+ }
+
+ /**
+ * Modify the userPaths.
+ *
+ * @param newUserPaths the userPaths to set
+ */
+ public void setUserPaths(List<String> newUserPaths) {
+ userPaths = newUserPaths;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONArray array = (JSONArray) JSONParser.parse(text);
+ if (array != null)
+ for (int i = 0; i < array.size(); i++)
+ if(array.get(i).isString() != null)
+ getUserPaths().add(array.get(i).isString().stringValue());
+ }
+ @Override
+ public String getName() {
+ String[] names = uri.split("/");
+ return URL.decodeComponent(names[names.length - 1]);
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+
+
+/**
+ * @author kman
+ *
+ */
+public class GroupUserResource extends RestResource{
+
+ public GroupUserResource(String aUri) {
+ super(aUri);
+ }
+
+ String username;
+ String name;
+ String home;
+
+ /**
+ * Retrieve the username.
+ *
+ * @return the username
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * Modify the username.
+ *
+ * @param aUsername the username to set
+ */
+ public void setUsername(String aUsername) {
+ username = aUsername;
+ }
+
+ /**
+ * Retrieve the name.
+ *
+ * @return the name
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Modify the name.
+ *
+ * @param aName the name to set
+ */
+ public void setName(String aName) {
+ name = aName;
+ }
+
+ /**
+ * Retrieve the home.
+ *
+ * @return the home
+ */
+ public String getHome() {
+ return home;
+ }
+
+ /**
+ * Modify the home.
+ *
+ * @param aHome the home to set
+ */
+ public void setHome(String aHome) {
+ home = aHome;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONObject json = (JSONObject) JSONParser.parse(text);
+ name = unmarshallString(json, "name");
+ home = unmarshallString(json, "home");
+ username = unmarshallString(json, "username");
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+/**
+ * @author kman
+ */
+public class GroupsResource extends RestResource {
+
+ public GroupsResource(String aUri) {
+ super(aUri);
+ }
+
+ List<String> groupPaths = new ArrayList<String>();
+
+ /**
+ * Retrieve the groupPaths.
+ *
+ * @return the groupPaths
+ */
+ public List<String> getGroupPaths() {
+ return groupPaths;
+ }
+
+ /**
+ * Modify the groupPaths.
+ *
+ * @param newGroupPaths the groupPaths to set
+ */
+ public void setGroupPaths(List<String> newGroupPaths) {
+ groupPaths = newGroupPaths;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONArray array = (JSONArray) JSONParser.parse(text);
+ if (array != null)
+ for (int i = 0; i < array.size(); i++) {
+ JSONObject js = array.get(i).isObject();
+ if(js != null){
+ String groupUri = unmarshallString(js, "uri");
+ if(groupUri != null)
+ getGroupPaths().add(groupUri);
+ }
+ }
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+
+/**
+ * @author kman
+ *
+ */
+public class MyFolderResource extends RestResourceWrapper{
+
+ /**
+ * @param aUri
+ */
+ public MyFolderResource(FolderResource resource) {
+ super(resource);
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import org.gss_project.gss.web.client.rest.MultipleGetCommand;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand.Cached;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+import com.google.gwt.user.client.ui.TreeItem;
+
+
+/**
+ * @author kman
+ *
+ */
+public class OtherUserResource extends RestResource{
+ public OtherUserResource(String aUri) {
+ super(aUri);
+ }
+
+ String username;
+ List<String> filePaths = new LinkedList<String>();
+ List<String> subfolderPaths = new LinkedList<String>();
+ List<FolderResource> folders = new ArrayList<FolderResource>();
+ List<FileResource> files = new ArrayList<FileResource>();
+
+ private boolean filesExpanded=false;
+ /**
+ * Retrieve the username.
+ *
+ * @return the username
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * Modify the username.
+ *
+ * @param aUsername the username to set
+ */
+ public void setUsername(String aUsername) {
+ username = aUsername;
+ }
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<String> getFilePaths() {
+ return filePaths;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFiles the files to set
+ */
+ public void setFilePaths(List<String> newFiles) {
+ filePaths = newFiles;
+ }
+
+ /**
+ * Retrieve the subfolders.
+ *
+ * @return the subfolders
+ */
+ public List<String> getSubfolderPaths() {
+ return subfolderPaths;
+ }
+
+ /**
+ * Modify the subfolders.
+ *
+ * @param subfolders the subfolders to set
+ */
+ public void setSubfolderPaths(List<String> subfolders) {
+ subfolderPaths = subfolders;
+ }
+
+ /**
+ * Retrieve the folders.
+ *
+ * @return the folders
+ */
+ public List<FolderResource> getFolders() {
+ return folders;
+ }
+
+ /**
+ * Modify the folders.
+ *
+ * @param newFolders the folders to set
+ */
+ public void setFolders(List<FolderResource> newFolders) {
+ folders = newFolders;
+ }
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<FileResource> getFiles() {
+ return files;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFiles the files to set
+ */
+ public void setFiles(List<FileResource> newFiles) {
+ files = newFiles;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONObject json = (JSONObject) JSONParser.parse(text);
+ if (json.get("folders") != null) {
+ JSONArray subs = json.get("folders").isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject so = subs.get(i).isObject();
+ if (so != null) {
+ String subUri = unmarshallString(so, "uri");
+ String subName = unmarshallString(so, "name");
+ if (subUri != null && subName != null) {
+ if (!subUri.endsWith("/"))
+ subUri = subUri + "/";
+ FolderResource sub = new FolderResource(subUri);
+ sub.setName(subName);
+ sub.setNeedsExpanding(true);
+ folders.add(sub);
+ subfolderPaths.add(subUri);
+ }
+ }
+ }
+ }
+ if (json.get("files") != null) {
+ JSONArray subs = json.get("files").isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject fo = subs.get(i).isObject();
+ if (fo != null) {
+ String fname = unmarshallString(fo, "name");
+ String fowner = unmarshallString(fo, "owner");
+ String fcontent = unmarshallString(fo, "content");
+ Boolean fshared = unmarshallBoolean(fo,"shared");
+ boolean fversioned = unmarshallBoolean(fo,"versioned");
+ Integer fversion = null;
+ if (fo.get("version") != null)
+ fversion = new Integer(fo.get("version").toString());
+ boolean fdeleted = unmarshallBoolean(fo, "deleted");
+ Date fcreationDate = null;
+ if (fo.get("creationDate") != null)
+ fcreationDate = new Date(new Long(fo.get("creationDate").toString()));
+ Date fmodificationDate = null;
+ if (fo.get("modificationDate") != null)
+ fmodificationDate = new Date(new Long(fo.get("modificationDate").toString()));
+ String furi = unmarshallString(fo,"uri");
+ Long fsize = 0L;
+ if(fo.get("size") != null)
+ fsize = new Long(fo.get("size").toString());
+ filePaths.add(furi);
+ String fpath = unmarshallString(fo, "path");
+ fpath = URL.decodeComponent(fpath);
+ FileResource fs = new FileResource(furi);
+ fs.setName(fname);
+ fs.setPath(fpath);
+ fs.setOwner(fowner);
+ fs.setVersion(fversion);
+ fs.setContentLength(fsize);
+ fs.setDeleted(fdeleted);
+ fs.setCreationDate(fcreationDate);
+ fs.setModificationDate(fmodificationDate);
+ fs.setShared(fshared);
+ fs.setVersioned(fversioned);
+ fs.setContentType(fcontent);
+ files.add(fs);
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getName(){
+ String[] names = uri.split("/");
+ return names[names.length -1];
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+
+ public MultipleGetCommand.Cached[] getFileCache(){
+ if(getFilePaths().size() != getFiles().size()){
+ GWT.log("MISMATCH IN PATH AND FILES SIZE", null);
+ return null;
+ }
+ if(!filesExpanded)
+ return null;
+ MultipleGetCommand.Cached[] result = new MultipleGetCommand.Cached[getFilePaths().size()];
+ for(int i=0; i<getFiles().size();i++){
+ FileResource r = getFiles().get(i);
+ Cached c = new Cached();
+ c.cache=r;
+ c.uri=r.uri;
+ result[i] = c;
+ }
+ return result;
+ }
+
+ public void setFilesExpanded(boolean newFilesExpanded) {
+ filesExpanded = newFilesExpanded;
+ }
+
+ @Override
+ public String constructUri(TreeItem treeItem, String path){
+ String constructedUri = "Files/others/"+ getName();
+ return constructedUri;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+
+/**
+ * @author kman
+ *
+ */
+public class OthersFolderResource extends RestResourceWrapper{
+
+ /**
+ * @param aUri
+ */
+ public OthersFolderResource(FolderResource resource) {
+ super(resource);
+ this.resource = resource;
+ // TODO Auto-generated constructor stub
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+import com.google.gwt.user.client.ui.TreeItem;
+
+/**
+ * @author kman
+ */
+public class OthersResource extends RestResource {
+
+ public OthersResource(String aUri) {
+ super(aUri);
+ }
+
+ List<String> others = new ArrayList<String>();
+ List<OtherUserResource> otherUsers = new ArrayList<OtherUserResource>();
+
+ /**
+ * Retrieve the others.
+ *
+ * @return the others
+ */
+ public List<String> getOthers() {
+ return others;
+ }
+
+ /**
+ * Modify the others.
+ *
+ * @param newOthers the others to set
+ */
+ public void setOthers(List<String> newOthers) {
+ others = newOthers;
+ }
+
+ public List<OtherUserResource> getOtherUsers() {
+ return otherUsers;
+ }
+
+ public void setOtherUsers(List<OtherUserResource> newOtherUsers) {
+ otherUsers = newOtherUsers;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONArray array = (JSONArray) JSONParser.parse(text);
+ if (array != null)
+ for (int i = 0; i < array.size(); i++) {
+ JSONObject js = array.get(i).isObject();
+ if (js != null) {
+ String othersUri = unmarshallString(js, "uri");
+ String username = unmarshallString(js, "username");
+ if(othersUri != null){
+ getOthers().add(othersUri);
+ OtherUserResource r = new OtherUserResource(othersUri);
+ r.setUsername(username);
+ getOtherUsers().add(r);
+ }
+ }
+ }
+ }
+
+ public String getUsernameOfUri(String u){
+ if(!u.endsWith("/"))
+ u=u+"/";
+ for(OtherUserResource o : getOtherUsers()){
+ GWT.log("CHECKING USER URI:"+o.getUri(), null);
+ String toCheck = o.getUri();
+ if(!toCheck.endsWith("/"))
+ toCheck=toCheck+"/";
+ if(toCheck.equals(u))
+ return o.getUsername();
+ }
+ return null;
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+
+ @Override
+ public String constructUri(TreeItem treeItem,String path){
+ String constructedUri = "Files/"+ path.substring(path.lastIndexOf("/")+1) + "others/";
+ return constructedUri;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.io.Serializable;
+
+
+/**
+ * @author kman
+ *
+ */
+public class PermissionHolder implements Serializable{
+
+ private String user;
+ private String group;
+ private boolean read;
+ private boolean write;
+ private boolean modifyACL;
+
+ /**
+ * Retrieve the user.
+ *
+ * @return the user
+ */
+ public String getUser() {
+ return user;
+ }
+
+ /**
+ * Modify the user.
+ *
+ * @param aUser the user to set
+ */
+ public void setUser(String aUser) {
+ user = aUser;
+ }
+
+ /**
+ * Retrieve the group.
+ *
+ * @return the group
+ */
+ public String getGroup() {
+ return group;
+ }
+
+ /**
+ * Modify the group.
+ *
+ * @param aGroup the group to set
+ */
+ public void setGroup(String aGroup) {
+ group = aGroup;
+ }
+
+ /**
+ * Retrieve the read.
+ *
+ * @return the read
+ */
+ public boolean isRead() {
+ return read;
+ }
+
+ /**
+ * Modify the read.
+ *
+ * @param aRead the read to set
+ */
+ public void setRead(boolean aRead) {
+ read = aRead;
+ }
+
+ /**
+ * Retrieve the write.
+ *
+ * @return the write
+ */
+ public boolean isWrite() {
+ return write;
+ }
+
+ /**
+ * Modify the write.
+ *
+ * @param aWrite the write to set
+ */
+ public void setWrite(boolean aWrite) {
+ write = aWrite;
+ }
+
+ /**
+ * Retrieve the modifyACL.
+ *
+ * @return the modifyACL
+ */
+ public boolean isModifyACL() {
+ return modifyACL;
+ }
+
+ /**
+ * Modify the modifyACL.
+ *
+ * @param aModifyACL the modifyACL to set
+ */
+ public void setModifyACL(boolean aModifyACL) {
+ modifyACL = aModifyACL;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.io.Serializable;
+
+import com.google.gwt.i18n.client.NumberFormat;
+
+
+/**
+ * @author kman
+ *
+ */
+public class QuotaHolder implements Serializable{
+ private Long fileCount = 0L;
+ private Long fileSize = 0L;
+ private Long quotaLeftSize = 0L;
+
+ /**
+ * Retrieve the fileCount.
+ *
+ * @return the fileCount
+ */
+ public Long getFileCount() {
+ return fileCount;
+ }
+
+ /**
+ * Modify the fileCount.
+ *
+ * @param aFileCount the fileCount to set
+ */
+ public void setFileCount(Long aFileCount) {
+ fileCount = aFileCount;
+ }
+
+ /**
+ * Retrieve the fileSize.
+ *
+ * @return the fileSize
+ */
+ public Long getFileSize() {
+ return fileSize;
+ }
+
+ /**
+ * Modify the fileSize.
+ *
+ * @param aFileSize the fileSize to set
+ */
+ public void setFileSize(Long aFileSize) {
+ fileSize = aFileSize;
+ }
+
+ /**
+ * Retrieve the quotaLeftSize.
+ *
+ * @return the quotaLeftSize
+ */
+ public Long getQuotaLeftSize() {
+ return quotaLeftSize;
+ }
+
+ /**
+ * Modify the quotaLeftSize.
+ *
+ * @param aQuotaLeftSize the quotaLeftSize to set
+ */
+ public void setQuotaLeftSize(Long aQuotaLeftSize) {
+ quotaLeftSize = aQuotaLeftSize;
+ }
+
+ public String getFileSizeAsString() {
+ if (fileSize < 1024)
+ return String.valueOf(fileSize) + " B";
+ else if (fileSize < 1024*1024)
+ return getSize(fileSize, 1024D) + " KB";
+ else if (fileSize < 1024*1024*1024)
+ return getSize(fileSize,(1024D*1024D)) + " MB";
+ return getSize(fileSize , (1024D*1024D*1024D)) + " GB";
+ }
+
+ public String getQuotaLeftAsString() {
+ if (quotaLeftSize < 1024)
+ return String.valueOf(quotaLeftSize) + " B";
+ else if (quotaLeftSize < 1024*1024)
+ return getSize(quotaLeftSize, 1024D) + " KB";
+ else if (quotaLeftSize < 1024*1024*1024)
+ return getSize(quotaLeftSize,(1024D*1024D)) + " MB";
+ return getSize(quotaLeftSize , (1024D*1024D*1024D)) + " GB";
+ }
+
+ private String getSize(Long size, Double division){
+ Double res = Double.valueOf(size.toString())/division;
+ NumberFormat nf = NumberFormat.getFormat("######.#");
+ return nf.format(res);
+ }
+
+ public long percentOfFreeSpace(){
+ return (long) ((double)quotaLeftSize*100/(fileSize+quotaLeftSize)+0.5);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.io.Serializable;
+
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.user.client.ui.TreeItem;
+
+
+/**
+ * @author kman
+ *
+ */
+public abstract class RestResource implements Serializable{
+ String uri;
+
+ public RestResource(String aUri) {
+ super();
+ setUri(aUri);
+ }
+
+ /**
+ * Retrieve the uri.
+ *
+ * @return the uri
+ */
+ public String getUri() {
+ return uri;
+ }
+
+ /**
+ * Modify the uri.
+ *
+ * @param aUri the path to set
+ */
+ public void setUri(String aUri) {
+ uri = aUri;
+ if (uri!=null) {
+ // Remove any parameter part
+ int qm = uri.indexOf('?');
+ if (qm>=0) uri = uri.substring(0, qm);
+ }
+ }
+
+ public abstract void createFromJSON(String text);
+
+ protected String unmarshallString(JSONObject obj, String key){
+ if(obj.get(key) != null)
+ if(obj.get(key).isString() != null)
+ return obj.get(key).isString().stringValue();
+ return null;
+ }
+
+ protected int unmarshallInt(JSONObject obj, String key){
+ if(obj.get(key) != null)
+ if(obj.get(key).isNumber() != null)
+ return (int) obj.get(key).isNumber().getValue();
+ return -1;
+ }
+
+ protected boolean unmarshallBoolean(JSONObject obj, String key){
+ if(obj.get(key) != null)
+ if(obj.get(key).isBoolean() != null)
+ return obj.get(key).isBoolean().booleanValue();
+ return false;
+ }
+
+ public static native String getDate(Long ms)/*-{
+ return (new Date(ms)).toUTCString();
+ }-*/;
+
+ public abstract String getLastModifiedSince();
+
+ public String constructUri(@SuppressWarnings("unused") TreeItem treeItem, @SuppressWarnings("unused") String path){
+ return "";
+ }
+
+ public String getName(){
+ String[] names = uri.split("/");
+ return names[names.length -1];
+ }
+}
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+
+/**
+ * @author kman
+ *
+ */
+public class RestResourceWrapper extends RestResource{
+ FolderResource resource;
+
+ public RestResourceWrapper(FolderResource resource) {
+ super(resource.getUri());
+ this.resource=resource;
+ }
+
+
+ /**
+ * Modify the resource.
+ *
+ * @param resource the resource to set
+ */
+ public void setResource(FolderResource resource) {
+ this.resource = resource;
+ }
+ /**
+ * Retrieve the resource.
+ *
+ * @return the resource
+ */
+ public FolderResource getResource() {
+ return resource;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.google.gwt.http.client.URL;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+
+/**
+ * @author kman
+ */
+public class SearchResource extends RestResource {
+ int size;
+ public SearchResource(String aUri) {
+ super(aUri);
+ }
+
+ List<FileResource> files = new ArrayList<FileResource>();
+ List<String> filePaths = new LinkedList<String>();
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<String> getFilePaths() {
+ return filePaths;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFilePaths the files to set
+ */
+ public void setFilePaths(List<String> newFilePaths) {
+ filePaths = newFilePaths;
+ }
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<FileResource> getFiles() {
+ return files;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFiles the files to set
+ */
+ public void setFiles(List<FileResource> newFiles) {
+ files = newFiles;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONArray subs = JSONParser.parse(text).isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject fo = subs.get(i).isObject();
+ if (fo != null) {
+ if(i==0&&unmarshallInt(fo, "length")!=-1){
+ setSize(unmarshallInt(fo, "length"));
+ }
+ else{
+ String fname = unmarshallString(fo, "name");
+ String fowner = unmarshallString(fo, "owner");
+ String fcontent = unmarshallString(fo, "content");
+ String fpath = unmarshallString(fo, "path");
+ Boolean fshared = unmarshallBoolean(fo,"shared");
+ boolean fversioned = unmarshallBoolean(fo,"versioned");
+ fpath = URL.decodeComponent(fpath);
+ Integer fversion = null;
+ if (fo.get("version") != null)
+ fversion = new Integer(fo.get("version").toString());
+ boolean fdeleted = unmarshallBoolean(fo, "deleted");
+ Date fcreationDate = null;
+ if (fo.get("creationDate") != null)
+ fcreationDate = new Date(new Long(fo.get("creationDate").toString()));
+ Date fmodificationDate = null;
+ if (fo.get("modificationDate") != null)
+ fmodificationDate = new Date(new Long(fo.get("modificationDate").toString()));
+ String furi = unmarshallString(fo,"uri");
+ Long fsize = 0L;
+ if(fo.get("size") != null)
+ fsize = new Long(fo.get("size").toString());
+ filePaths.add(furi);
+ FileResource fs = new FileResource(furi);
+ fs.setName(fname);
+ fs.setOwner(fowner);
+ fs.setVersion(fversion);
+ fs.setContentLength(fsize);
+ fs.setDeleted(fdeleted);
+ fs.setCreationDate(fcreationDate);
+ fs.setModificationDate(fmodificationDate);
+ fs.setContentType(fcontent);
+ fs.setPath(fpath);
+ fs.setShared(fshared);
+ fs.setVersioned(fversioned);
+ files.add(fs);
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+
+
+ /**
+ * Retrieve the size.
+ *
+ * @return the size
+ */
+ public int getSize() {
+ return size;
+ }
+
+
+ /**
+ * Modify the size.
+ *
+ * @param size the size to set
+ */
+ public void setSize(int size) {
+ this.size = size;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+
+/**
+ * @author kman
+ *
+ */
+public class SharedFolderResource extends RestResourceWrapper{
+
+ /**
+ * @param aUri
+ */
+ public SharedFolderResource(FolderResource resource) {
+ super(resource);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import org.gss_project.gss.web.client.rest.MultipleGetCommand;
+import org.gss_project.gss.web.client.rest.MultipleGetCommand.Cached;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+import com.google.gwt.user.client.ui.TreeItem;
+
+
+/**
+ * @author kman
+ *
+ */
+public class SharedResource extends RestResource{
+
+ public SharedResource(String aUri) {
+ super(aUri);
+ }
+
+ List<String> filePaths = new LinkedList<String>();
+ List<String> subfolderPaths = new LinkedList<String>();
+ List<FolderResource> folders = new ArrayList<FolderResource>();
+
+ List<FileResource> files = new ArrayList<FileResource>();
+
+ private boolean filesExpanded=false;
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<String> getFilePaths() {
+ return filePaths;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFilePaths the files to set
+ */
+ public void setFilePaths(List<String> newFilePaths) {
+ filePaths = newFilePaths;
+ }
+
+ /**
+ * Retrieve the subfolders.
+ *
+ * @return the subfolders
+ */
+ public List<String> getSubfolderPaths() {
+ return subfolderPaths;
+ }
+
+ /**
+ * Modify the subfolder paths.
+ *
+ * @param newSubfolderPaths the subfolder paths to set
+ */
+ public void setSubfolderPaths(List<String> newSubfolderPaths) {
+ subfolderPaths = newSubfolderPaths;
+ }
+
+ /**
+ * Retrieve the folders.
+ *
+ * @return the folders
+ */
+ public List<FolderResource> getFolders() {
+ return folders;
+ }
+
+ /**
+ * Modify the folders.
+ *
+ * @param newFolders the folders to set
+ */
+ public void setFolders(List<FolderResource> newFolders) {
+ folders = newFolders;
+ }
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<FileResource> getFiles() {
+ return files;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFiles the files to set
+ */
+ public void setFiles(List<FileResource> newFiles) {
+ files = newFiles;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONObject json = (JSONObject) JSONParser.parse(text);
+ if (json.get("folders") != null) {
+ JSONArray subs = json.get("folders").isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject so = subs.get(i).isObject();
+ if (so != null) {
+ String subUri = unmarshallString(so, "uri");
+ String subName = unmarshallString(so, "name");
+ if (subUri != null && subName != null) {
+ if (!subUri.endsWith("/"))
+ subUri = subUri + "/";
+ FolderResource sub = new FolderResource(subUri);
+ sub.setName(subName);
+ sub.setNeedsExpanding(true);
+ folders.add(sub);
+ subfolderPaths.add(subUri);
+ }
+ }
+ }
+ }
+ if (json.get("files") != null) {
+ JSONArray subs = json.get("files").isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject fo = subs.get(i).isObject();
+ if (fo != null) {
+ String fname = unmarshallString(fo, "name");
+ String fowner = unmarshallString(fo, "owner");
+ String fcontent = unmarshallString(fo, "content");
+ boolean fversioned = unmarshallBoolean(fo, "versioned");
+ Integer fversion = null;
+ if (fo.get("version") != null)
+ fversion = new Integer(fo.get("version").toString());
+ boolean fdeleted = unmarshallBoolean(fo, "deleted");
+ Date fcreationDate = null;
+ if (fo.get("creationDate") != null)
+ fcreationDate = new Date(new Long(fo.get("creationDate").toString()));
+ Date fmodificationDate = null;
+ if (fo.get("modificationDate") != null)
+ fmodificationDate = new Date(new Long(fo.get("modificationDate").toString()));
+ String furi = unmarshallString(fo,"uri");
+ Long fsize = 0L;
+ if(fo.get("size") != null)
+ fsize = new Long(fo.get("size").toString());
+ filePaths.add(furi);
+ String fpath = unmarshallString(fo, "path");
+ fpath = URL.decodeComponent(fpath);
+ FileResource fs = new FileResource(furi);
+ fs.setPath(fpath);
+ fs.setName(fname);
+ fs.setOwner(fowner);
+ fs.setVersion(fversion);
+ fs.setVersioned(unmarshallBoolean(fo, "versioned"));
+ fs.setContentLength(fsize);
+ fs.setDeleted(fdeleted);
+ fs.setShared(unmarshallBoolean(fo,"shared"));
+ fs.setVersioned(fversioned);
+ fs.setCreationDate(fcreationDate);
+ fs.setModificationDate(fmodificationDate);
+ fs.setContentType(fcontent);
+ files.add(fs);
+ }
+ }
+ }
+ }
+
+ public List<String> getRootSharedFiles(){
+ List<String> res = new ArrayList<String>();
+ for(String f : getFilePaths()){
+ boolean contained = false;
+ for(String fo : getSubfolderPaths())
+ if(f.startsWith(fo))
+ contained = true;
+ if(!contained)
+ res.add(f);
+ }
+ return res;
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+
+ public MultipleGetCommand.Cached[] getFileCache(){
+ if(getFilePaths().size() != getFiles().size()){
+ GWT.log("MISMATCH IN PATH AND FILES SIZE", null);
+ return null;
+ }
+ if(!filesExpanded)
+ return null;
+ MultipleGetCommand.Cached[] result = new MultipleGetCommand.Cached[getFilePaths().size()];
+ for(int i=0; i<getFiles().size();i++){
+ FileResource r = getFiles().get(i);
+ Cached c = new Cached();
+ c.cache=r;
+ c.uri=r.uri;
+ result[i] = c;
+ }
+ return result;
+ }
+
+ public void setFilesExpanded(boolean newFilesExpanded) {
+ filesExpanded = newFilesExpanded;
+ }
+
+ @Override
+ public String constructUri(TreeItem treeItem, String path){
+ String constructedUri = "Files/"+ getUri().substring(path.lastIndexOf("/")+1);
+ return constructedUri;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONParser;
+
+
+/**
+ * @author kman
+ *
+ */
+public class TagsResource extends RestResource{
+
+ public TagsResource(String aUri) {
+ super(aUri);
+ }
+
+ List<String> tags = new ArrayList<String>();
+
+ /**
+ * Retrieve the tags.
+ *
+ * @return the tags
+ */
+ public List<String> getTags() {
+ return tags;
+ }
+
+ /**
+ * Modify the tags.
+ *
+ * @param newTags the tags to set
+ */
+ public void setTags(List<String> newTags) {
+ tags = newTags;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONArray array = (JSONArray) JSONParser.parse(text);
+ if(array != null)
+ for (int i = 0; i < array.size(); i++)
+ getTags().add(array.get(i).isString().stringValue());
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2011 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+
+/**
+ * @author kman
+ *
+ */
+public class TrashFolderResource extends RestResourceWrapper{
+
+ /**
+ * @param aUri
+ */
+ public TrashFolderResource(FolderResource resource) {
+ super(resource);
+
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright 2009, 2010 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.google.gwt.http.client.URL;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+import com.google.gwt.user.client.ui.TreeItem;
+
+
+/**
+ * @author kman
+ *
+ */
+public class TrashResource extends RestResource{
+
+ public TrashResource(String aUri) {
+ super(aUri);
+ }
+
+ List<String> filePaths = new LinkedList<String>();
+ List<String> subfolderPaths = new LinkedList<String>();
+ List<FolderResource> folders = new ArrayList<FolderResource>();
+ List<FileResource> files = new ArrayList<FileResource>();
+
+ /**
+ * Retrieve the file paths.
+ *
+ * @return the file paths
+ */
+ public List<String> getFilePaths() {
+ return filePaths;
+ }
+
+ /**
+ * Modify the file paths.
+ *
+ * @param newFilePaths the file paths to set
+ */
+ public void setFilePaths(List<String> newFilePaths) {
+ filePaths = newFilePaths;
+ }
+
+ /**
+ * Retrieve the subfolder paths.
+ *
+ * @return the subfolder paths
+ */
+ public List<String> getSubfolderPaths() {
+ return subfolderPaths;
+ }
+
+ /**
+ * Modify the subfolder paths.
+ *
+ * @param newSubfolderPaths the subfolders to set
+ */
+ public void setSubfolderPaths(List<String> newSubfolderPaths) {
+ subfolderPaths = newSubfolderPaths;
+ }
+
+ /**
+ * Retrieve the folders.
+ *
+ * @return the folders
+ */
+ public List<FolderResource> getFolders() {
+ return folders;
+ }
+
+ /**
+ * Modify the folders.
+ *
+ * @param newFolders the folders to set
+ */
+ public void setFolders(List<FolderResource> newFolders) {
+ folders = newFolders;
+ }
+
+ /**
+ * Retrieve the files.
+ *
+ * @return the files
+ */
+ public List<FileResource> getFiles() {
+ return files;
+ }
+
+ /**
+ * Modify the files.
+ *
+ * @param newFiles the files to set
+ */
+ public void setFiles(List<FileResource> newFiles) {
+ files = newFiles;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONObject json = (JSONObject) JSONParser.parse(text);
+ if (json.get("folders") != null) {
+ JSONArray subs = json.get("folders").isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject so = subs.get(i).isObject();
+ if (so != null) {
+ String subUri = unmarshallString(so, "uri");
+ String subName = unmarshallString(so, "name");
+ subName = URL.decodeComponent(subName);
+ if (subUri != null && subName != null) {
+ if (!subUri.endsWith("/"))
+ subUri = subUri + "/";
+ FolderResource sub = new FolderResource(subUri);
+ sub.setName(subName);
+ sub.setNeedsExpanding(true);
+ folders.add(sub);
+ subfolderPaths.add(subUri);
+ }
+ }
+ }
+ }
+ if (json.get("files") != null) {
+ JSONArray subs = json.get("files").isArray();
+ if (subs != null)
+ for (int i = 0; i < subs.size(); i++) {
+ JSONObject fo = subs.get(i).isObject();
+ if (fo != null) {
+ String fname = unmarshallString(fo, "name");
+ String fowner = unmarshallString(fo, "owner");
+ String fcontent = unmarshallString(fo, "content");
+ Boolean fshared = unmarshallBoolean(fo, "shared");
+ Boolean fversioned = unmarshallBoolean(fo, "versioned");
+ String fpath = unmarshallString(fo, "path");
+ fpath = URL.decodeComponent(fpath);
+ Integer fversion = null;
+ if (fo.get("version") != null)
+ fversion = new Integer(fo.get("version").toString());
+ boolean fdeleted = unmarshallBoolean(fo, "deleted");
+ Date fcreationDate = null;
+ if (fo.get("creationDate") != null)
+ fcreationDate = new Date(new Long(fo.get("creationDate").toString()));
+ Date fmodificationDate = null;
+ if (fo.get("modificationDate") != null)
+ fmodificationDate = new Date(new Long(fo.get("modificationDate").toString()));
+ String furi = unmarshallString(fo,"uri");
+ Long fsize = 0L;
+ if(fo.get("size") != null)
+ fsize = new Long(fo.get("size").toString());
+ filePaths.add(furi);
+ FileResource fs = new FileResource(furi);
+ fs.setName(fname);
+ fs.setOwner(fowner);
+ fs.setVersion(fversion);
+ fs.setContentLength(fsize);
+ fs.setDeleted(fdeleted);
+ fs.setPath(fpath);
+ fs.setCreationDate(fcreationDate);
+ fs.setModificationDate(fmodificationDate);
+ fs.setContentType(fcontent);
+ fs.setShared(fshared);
+ fs.setVersioned(fversioned);
+ files.add(fs);
+ }
+ }
+ }
+ }
+
+ public List<FolderResource> getTrashedFolders(){
+ List<FolderResource> res = new ArrayList<FolderResource>();
+ for(String s : subfolderPaths){
+ String[] pathElements = s.split("/");
+ FolderResource tr = new FolderResource(s);
+ tr.setName(URL.decodeComponent(pathElements[pathElements.length-1]));
+ res.add(tr);
+ }
+ return res;
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+ @Override
+ public String constructUri(TreeItem treeItem, String path){
+ String constructedUri = "Files/"+ getUri().substring(path.lastIndexOf("/")+1);
+ if (!constructedUri.endsWith("/"))
+ constructedUri += "/";
+ return constructedUri;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+
+
+/**
+ * @author kman
+ *
+ */
+public class UploadStatusResource extends RestResource{
+ long bytesTransferred;
+ long fileSize;
+
+ public UploadStatusResource(String aUri) {
+ super(aUri);
+ }
+
+ /**
+ * Retrieve the bytesTransferred.
+ *
+ * @return the bytesTransferred
+ */
+ public long getBytesTransferred() {
+ return bytesTransferred;
+ }
+
+ /**
+ * Modify the bytesTransferred.
+ *
+ * @param newBytesTransferred the bytesTransferred to set
+ */
+ public void setBytesTransferred(long newBytesTransferred) {
+ bytesTransferred = newBytesTransferred;
+ }
+
+ /**
+ * Retrieve the fileSize.
+ *
+ * @return the fileSize
+ */
+ public long getFileSize() {
+ return fileSize;
+ }
+
+ /**
+ * Modify the fileSize.
+ *
+ * @param newFileSize the fileSize to set
+ */
+ public void setFileSize(long newFileSize) {
+ fileSize = newFileSize;
+ }
+
+ public int percent(){
+ return new Long(bytesTransferred * 100 / fileSize).intValue();
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONObject json = (JSONObject) JSONParser.parse(text);
+ if(json.get("bytesTotal") != null)
+ fileSize = new Long(json.get("bytesTotal").toString());
+ if(json.get("bytesUploaded") != null)
+ bytesTransferred = new Long(json.get("bytesUploaded").toString());
+
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.Date;
+
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+
+/**
+ * @author kman
+ */
+public class UserResource extends RestResource {
+
+ public UserResource(String aUri) {
+ super(aUri);
+ }
+
+ private String name;
+
+ private String username;
+
+ private String email;
+
+ private Date creationDate;
+
+ private Date modificationDate;
+
+ private String filesPath;
+
+ private String trashPath;
+
+ private String sharedPath;
+
+ private String othersPath;
+
+ private String tagsPath;
+
+ private String groupsPath;
+
+ private QuotaHolder quota;
+
+ private String announcement;
+
+ private Date lastLogin;
+
+ private Date currentLogin;
+
+ /**
+ * Retrieve the name.
+ *
+ * @return the name
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Modify the name.
+ *
+ * @param aName the name to set
+ */
+ public void setName(String aName) {
+ name = aName;
+ }
+
+ /**
+ * Retrieve the username.
+ *
+ * @return the username
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * Modify the username.
+ *
+ * @param aUsername the username to set
+ */
+ public void setUsername(String aUsername) {
+ username = aUsername;
+ }
+
+ /**
+ * Retrieve the email.
+ *
+ * @return the email
+ */
+ public String getEmail() {
+ return email;
+ }
+
+ /**
+ * Modify the email.
+ *
+ * @param anEmail the email to set
+ */
+ public void setEmail(String anEmail) {
+ email = anEmail;
+ }
+
+ /**
+ * Retrieve the creationDate.
+ *
+ * @return the creationDate
+ */
+ public Date getCreationDate() {
+ return creationDate;
+ }
+
+ /**
+ * Modify the creationDate.
+ *
+ * @param aCreationDate the creationDate to set
+ */
+ public void setCreationDate(Date aCreationDate) {
+ creationDate = aCreationDate;
+ }
+
+ /**
+ * Retrieve the modificationDate.
+ *
+ * @return the modificationDate
+ */
+ public Date getModificationDate() {
+ return modificationDate;
+ }
+
+ /**
+ * Modify the modificationDate.
+ *
+ * @param aModificationDate the modificationDate to set
+ */
+ public void setModificationDate(Date aModificationDate) {
+ modificationDate = aModificationDate;
+ }
+
+ /**
+ * Retrieve the filesPath.
+ *
+ * @return the filesPath
+ */
+ public String getFilesPath() {
+ return filesPath;
+ }
+
+ /**
+ * Modify the filesPath.
+ *
+ * @param aFilesPath the filesPath to set
+ */
+ public void setFilesPath(String aFilesPath) {
+ filesPath = aFilesPath;
+ }
+
+ /**
+ * Retrieve the trashPath.
+ *
+ * @return the trashPath
+ */
+ public String getTrashPath() {
+ return trashPath;
+ }
+
+ /**
+ * Modify the trashPath.
+ *
+ * @param aTrashPath the trashPath to set
+ */
+ public void setTrashPath(String aTrashPath) {
+ trashPath = aTrashPath;
+ }
+
+ /**
+ * Retrieve the sharedPath.
+ *
+ * @return the sharedPath
+ */
+ public String getSharedPath() {
+ return sharedPath;
+ }
+
+ /**
+ * Modify the sharedPath.
+ *
+ * @param aSharedPath the sharedPath to set
+ */
+ public void setSharedPath(String aSharedPath) {
+ sharedPath = aSharedPath;
+ }
+
+ /**
+ * Retrieve the othersPath.
+ *
+ * @return the othersPath
+ */
+ public String getOthersPath() {
+ return othersPath;
+ }
+
+ /**
+ * Modify the othersPath.
+ *
+ * @param anOthersPath the othersPath to set
+ */
+ public void setOthersPath(String anOthersPath) {
+ othersPath = anOthersPath;
+ }
+
+ /**
+ * Retrieve the tagsPath.
+ *
+ * @return the tagsPath
+ */
+ public String getTagsPath() {
+ return tagsPath;
+ }
+
+ /**
+ * Modify the tagsPath.
+ *
+ * @param aTagsPath the tagsPath to set
+ */
+ public void setTagsPath(String aTagsPath) {
+ tagsPath = aTagsPath;
+ }
+
+ /**
+ * Retrieve the groupsPath.
+ *
+ * @return the groupsPath
+ */
+ public String getGroupsPath() {
+ return groupsPath;
+ }
+
+ /**
+ * Modify the groupsPath.
+ *
+ * @param aGroupsPath the groupsPath to set
+ */
+ public void setGroupsPath(String aGroupsPath) {
+ groupsPath = aGroupsPath;
+ }
+
+ /**
+ * Retrieve the quota.
+ *
+ * @return the quota
+ */
+ public QuotaHolder getQuota() {
+ return quota;
+ }
+
+ /**
+ * Modify the quota.
+ *
+ * @param aQuota the quota to set
+ */
+ public void setQuota(QuotaHolder aQuota) {
+ quota = aQuota;
+ }
+
+
+ /**
+ * Retrieve the announcement.
+ *
+ * @return the announcement
+ */
+ public String getAnnouncement() {
+ return announcement;
+ }
+
+ /**
+ * Modify the announcement.
+ *
+ * @param anAnnouncement the announcement to set
+ */
+ public void setAnnouncement(String anAnnouncement) {
+ announcement = anAnnouncement;
+ }
+
+ /**
+ * Retrieve the lastLogin.
+ *
+ * @return the lastLogin
+ */
+ public Date getLastLogin() {
+ return lastLogin;
+ }
+
+ /**
+ * Retrieve the currentLogin.
+ *
+ * @return the currentLogin
+ */
+ public Date getCurrentLogin() {
+ return currentLogin;
+ }
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONObject json = (JSONObject) JSONParser.parse(text);
+ email = unmarshallString(json, "email");
+ name = unmarshallString(json, "name");
+ username = unmarshallString(json, "username");
+ filesPath = unmarshallString(json, "fileroot");
+ groupsPath = unmarshallString(json, "groups");
+ othersPath = unmarshallString(json, "others");
+ sharedPath = unmarshallString(json, "shared");
+ tagsPath = unmarshallString(json, "tags");
+ trashPath = unmarshallString(json, "trash");
+ announcement = unmarshallString(json, "announcement");
+ if (json.get("lastLogin") != null)
+ lastLogin = new Date(new Long(json.get("lastLogin").toString()));
+ if (json.get("currentLogin") != null)
+ currentLogin = new Date(new Long(json.get("currentLogin").toString()));
+ if (json.get("creationDate") != null)
+ creationDate = new Date(new Long(json.get("creationDate").toString()));
+ if (json.get("modificationDate") != null)
+ modificationDate = new Date(new Long(json.get("modificationDate").toString()));
+ if (json.get("quota") != null) {
+ JSONObject qj = (JSONObject) json.get("quota");
+ if (qj != null) {
+ quota = new QuotaHolder();
+ if(qj.get("totalFiles") != null)
+ quota.setFileCount(new Long(qj.get("totalFiles").toString()));
+ if(qj.get("totalBytes") != null)
+ quota.setFileSize(new Long(qj.get("totalBytes").toString()));
+ if(qj.get("bytesRemaining") != null)
+ quota.setQuotaLeftSize(new Long(qj.get("bytesRemaining").toString()));
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ String res = email + "\n" + name + "\n" + username + "\n" + filesPath + "\n" + groupsPath;
+ return res;
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2009 Electronic Business Systems Ltd.
+ *
+ * This file is part of GSS.
+ *
+ * GSS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.gss_project.gss.web.client.rest.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+
+/**
+ * A container for the results of a search query for users.
+ *
+ * @author past
+ */
+public class UserSearchResource extends RestResource {
+
+ public UserSearchResource(String aUri) {
+ super(aUri);
+ }
+
+ List<UserResource> users = new ArrayList<UserResource>();
+
+ @Override
+ public void createFromJSON(String text) {
+ JSONArray json = JSONParser.parse(text).isArray();
+ if (json != null)
+ for (int i = 0; i < json.size(); i++) {
+ JSONObject j = json.get(i).isObject();
+ if (j != null) {
+ String username = unmarshallString(j, "username");
+ String name = unmarshallString(j, "name");
+ String home = unmarshallString(j, "home");
+ UserResource user = new UserResource(home);
+ user.setName(name);
+ user.setUsername(username);
+ users.add(user);
+ }
+ }
+ }
+
+ /**
+ * Retrieve the users.
+ *
+ * @return the users
+ */
+ public List<UserResource> getUsers() {
+ return users;
+ }
+
+ /**
+ * Modify the users.
+ *
+ * @param newUsers the users to set
+ */
+ public void setUsers(List<UserResource> newUsers) {
+ users = newUsers;
+ }
+
+ @Override
+ public String getLastModifiedSince() {
+ return null;
+ }
+}
--- /dev/null
+<html>
+ <head>
+ <title>Pithos</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <script language='javascript' src='org.gss_project.gss.web.GSS.nocache.js'></script>
+ <script type="text/javascript">
+ document.oncontextmenu = function() {
+ return false;
+ }
+ </script>
+ <script type="text/javascript" src="sha1.js"></script>
+ <script type="text/javascript" language="javascript" src="lytebox.js"></script>
+ <link rel="stylesheet" href="lytebox.css" type="text/css" media="screen" /> </head>
+ <body>
+ <iframe src="javascript:''" id="__gwt_historyFrame" style="position:absolute;width:0;height:0;border:0"></iframe>
+ </body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Pithos</title>
+ <link type="text/css" rel="stylesheet" href="/pithos/main.css">
+ </head>
+ <body>
+<div class="wrapper" >
+<div class="header"></div>
+<div class="image_logo">
+<table><tr>
+ <td><a href="/"><img src="/pithos/images/service-logo.png"></img></a>
+</tr></table>
+</div> <!-- image_logo -->
+<div style="clear: both; "> </div>
+<div class="page_main">
+ <center>
+ <p class="big">HTTP status 403
+ <p>You don't have permission to view the resource in the requested URI.
+ </center>
+</div>
+<div class="footer"></div>
+</div> <!-- wrapper -->
+ </body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Pithos</title>
+ <link type="text/css" rel="stylesheet" href="/pithos/main.css">
+ </head>
+ <body>
+<div class="wrapper" >
+<div class="header"></div>
+<div class="image_logo">
+<table><tr>
+ <td><a href="/"><img src="/pithos/images/service-logo.png"></img></a>
+</tr></table>
+</div> <!-- image_logo -->
+<div style="clear: both; "> </div>
+<div class="page_main">
+ <center>
+ <p class="big">HTTP status 502
+ <p>The server received an invalid response from the upstream server it accessed in attempting to fulfill the request.
+ </center>
+</div>
+<div class="footer"></div>
+</div> <!-- wrapper -->
+ </body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Pithos</title>
+ <link type="text/css" rel="stylesheet" href="/pithos/main.css">
+ </head>
+ <body>
+<div class="wrapper" >
+<div class="header"></div>
+<div class="image_logo">
+<table><tr>
+ <td><a href="/"><img src="/pithos/images/service-logo.png"></img></a>
+</tr></table>
+</div> <!-- image_logo -->
+<div style="clear: both; "> </div>
+<div class="page_main">
+ <center>
+ <p class="big">HTTP status 503
+ <p>We're very busy at the moment and can't handle your request.
+ Please try again in a while.
+ </center>
+</div>
+<div class="footer"></div>
+</div> <!-- wrapper -->
+ </body>
+</html>
--- /dev/null
+body {
+ background-color: #bec8e6;
+ color: black;
+ font-family: "Lucida Grande","Lucida Sans Unicode",Arial,Verdana,sans-serif;
+ font-size: small;
+ margin: 8px;
+ margin-top: 3px;
+}
+
+a {
+ color: darkblue;
+}
+
+a:visited {
+ color: darkblue;
+}
+
+.hidden-link {
+ text-decoration: none !important;
+ color: black !important;
+}
+
+.hidden-link:visited {
+ text-decoration: none !important;
+ color: black !important;
+}
+
+.gss-TopPanel {
+ font-size: 100%;
+}
+
+.gss-TopPanelLinks {
+ font-size: 100%;
+}
+
+.gss-AboutText {
+ width: 24em;
+ /* Restore the padding we remove when overriding the gwt-DialogBox style */
+ padding: 3px;
+}
+
+.gss-Groups {
+ background-color: white;
+ font-size: 80%;
+}
+
+.toolbar {
+ border: 1px solid #AAAAAA;
+ background-color: white;
+ font-size: 80%;
+ cursor: pointer;
+}
+
+.toolbarmenu {
+ font-size: 80%;
+ cursor: pointer;
+}
+
+.statusbar-inner {
+ border: none;
+ font-size: 90%;
+ vertical-align: middle;
+ font-weight: normal;
+}
+
+.gss-List {
+ background-color: white;
+ font-size: 80%;
+ cursor: default;
+ border-collapse: collapse;
+ /* prevents selecting text in table with shift and ctrl*/
+ -moz-user-select: none;
+}
+.gss-List thead tr{
+ border: 1px lightblue solid;
+ }
+
+ .GK31MSKBKG{
+ border-bottom:none;
+ }
+.gss-ListHeader {
+
+ background-color: #E0EDFE;
+ font-weight: bold;
+ cursor: pointer;
+}
+
+.gss-searchLabel {
+ font-weight: bold;
+ font-style: italic;
+ font-size: 90%;
+ padding:5px;
+}
+
+.gss-ListNavBar {
+ font-size: 80%;
+}
+
+.gss-SelectedRow {
+ background-color: #E0EDFE;
+}
+.gss-fileRow{
+ cursor: pointer;
+}
+
+.gss-Toolbar {
+}
+
+.gss-ToolButton {
+ font-size: 80%;
+ width: 10em;
+}
+
+.props-labels {
+ font-size: 80%;
+ font-weight: bold;
+}
+
+.props-toplabels {
+ font-size: 80%;
+ font-weight: bold;
+ font-style: italic;
+}
+
+.props-values {
+ font-size: 80%;
+}
+
+.gss-errorMessage {
+ font-size: 90%;
+ background-color: #ff9999;
+ cursor: pointer;
+}
+
+.gss-warnMessage {
+ font-size: 90%;
+ background-color: #eeee99;
+ cursor: pointer;
+}
+
+.gss-infoMessage {
+ font-size: 90%;
+ background-color: #ccffcc;
+ cursor: pointer;
+}
+
+.gss-clearMessage {
+ font-size: 90%;
+ font-weight: bold;
+ text-decoration: none;
+ color: black;
+}
+
+.gss-clearMessage:visited {
+ font-size: 90%;
+ font-weight: bold;
+ text-decoration: none;
+ color: black;
+}
+
+.gss-search {
+ color: black;
+}
+
+.gss-search-empty {
+ color: #d3d3d3;
+}
+
+.gss-DialogBox {
+}
+
+.gss-readForAllNote {
+ width: 240px;
+ text-align: justify;
+ font-style: italic;
+ font-size: 12px;
+ padding-left: 4;
+}
+
+/* Tooltips */
+a.info {
+ position: relative; /*this is the key*/
+ z-index: 24;
+ color: black;
+ text-decoration: none
+}
+
+a.info:hover {
+ z-index: 25;
+ background-color: yellow;
+}
+
+a.info div {
+ display: none
+}
+
+a.info:hover span {
+ cursor: pointer;
+}
+
+/* The span will only display on :hover state. */
+a.info:hover div {
+ display: block;
+ position: absolute;
+ bottom: 2em;
+ right: 1em;
+ width: 10em;
+ border: 1px solid lightblue;
+ background-color: #D0E4F6;
+ color: black;
+ text-align: center
+}
+
+table.gss-permList.props-labels {
+ font-weight: bold;
+}
+
+table.gss-permList {
+ border-spacing: 3px;
+ border-collapse: collapse;
+
+}
+
+table.gss-permList td {
+ padding: 5px 5px 5px 5px;
+ font-size:80%;
+}
+
+.progressbar-text {
+ font-weight: bold;
+}
+
+.progressbar-remaining {
+ font-size: 12px;
+ font-style: italic;
+}
+
+.progressbar-outer {
+}
+
+.progressbar-inner {
+ border: 1px solid darkgrey;
+ margin: 1px;
+}
+
+.progressbar-bar {
+ width: 5px;
+ height: 15px;
+ margin: 0px;
+}
+
+.progressbar-fullbar {
+ background: #E0EDFE;
+}
+
+.progressbar-blankbar {
+ background: white;
+}
+
+.gss-uploadNote {
+ text-align: justify;
+ font-style: italic;
+ font-size: 12px;
+ padding-top: 16;
+ padding-bottom: 16;
+ padding-right: 4;
+ padding-left: 4;
+}
+
+.gss-MainTabBar {
+ padding-top: 4px;
+}
+
+.gss-MainTabPanelBottom {
+ border-bottom: none;
+ border-left: none;
+ border-right: none;
+ overflow: hidden;
+ padding: 6px;
+}
+
+.gss-TabPanelBottom {
+ border-color: darkgrey;
+ border-width: 1px 1px 1px;
+ overflow: hidden;
+ padding: 6px;
+}
+
+.gss-splitPanel {
+ background-color: white;
+ border: 1px solid darkgrey;
+}
+
+.gss-tag {
+ display:inline;
+}
+
+/* Use the background color for the splitter. */
+.gwt-HorizontalSplitPanel .hsplitter {
+ cursor: move;
+ border: 0px;
+ background: #bec8e6;
+}
+
+/* Avoid extended background color in tree nodes. */
+.gwt-TreeItem-selected .gwt-HTML {
+ display: inline;
+}
+
+/*
+ * Remove the padding inside the dialog boxes so that our background color
+ * appears uniform in warnings and errors.
+ */
+.gwt-DialogBox .dialogMiddleCenter {
+ background:none repeat scroll 0 0 white;
+ padding: 0;
+}
+
+.droppableHover {
+ background-color: #C1DEFD;
+}
--- /dev/null
+<html>
+ <head>
+ <title>Pithos</title>
+ <link type="text/css" rel="stylesheet" href="gss.css">
+ </head>
+ <body>
+ <center>
+ <p>Thank you for using Pithos.
+ <p><a href='/pithos/'>Login again</a>
+ </center>
+ </body>
+</html>
--- /dev/null
+#lbOverlay { position: fixed; top: 0; left: 0; z-index: 99998; width: 100%; height: 500px; }\r
+ #lbOverlay.grey { background-color: #000000; }\r
+ #lbOverlay.red { background-color: #330000; }\r
+ #lbOverlay.green { background-color: #003300; }\r
+ #lbOverlay.blue { background-color: #011D50; }\r
+ #lbOverlay.gold { background-color: #666600; }\r
+\r
+#lbMain { position: absolute; left: 0; width: 100%; z-index: 99999; text-align: center; line-height: 0; }\r
+#lbMain a img { border: none; }\r
+\r
+#lbOuterContainer { position: relative; background-color: #fff; width: 200px; height: 200px; margin: 0 auto; }\r
+ #lbOuterContainer.grey { border: 3px solid #888888; }\r
+ #lbOuterContainer.red { border: 3px solid #DD0000; }\r
+ #lbOuterContainer.green { border: 3px solid #00B000; }\r
+ #lbOuterContainer.blue { border: 3px solid #5F89D8; }\r
+ #lbOuterContainer.gold { border: 3px solid #B0B000; }\r
+\r
+#lbDetailsContainer { font: 10px Verdana, Helvetica, sans-serif; background-color: #fff; width: 100%; line-height: 1.4em; overflow: auto; margin: 0 auto; }\r
+ #lbDetailsContainer.grey { border: 3px solid #888888; border-top: none; }\r
+ #lbDetailsContainer.red { border: 3px solid #DD0000; border-top: none; }\r
+ #lbDetailsContainer.green { border: 3px solid #00B000; border-top: none; }\r
+ #lbDetailsContainer.blue { border: 3px solid #5F89D8; border-top: none; }\r
+ #lbDetailsContainer.gold { border: 3px solid #B0B000; border-top: none; }\r
+\r
+#lbImageContainer, #lbIframeContainer { padding: 10px; }\r
+#lbLoading {\r
+ position: absolute; top: 45%; left: 0%; height: 32px; width: 100%; text-align: center; line-height: 0; background: url(images/loading.gif) center no-repeat;\r
+}\r
+\r
+#lbHoverNav { position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 10; }\r
+#lbImageContainer>#lbHoverNav { left: 0; }\r
+#lbHoverNav a { outline: none; }\r
+\r
+#lbPrev { width: 49%; height: 100%; background: transparent url(images/blank.gif) no-repeat; display: block; left: 0; float: left; }\r
+ #lbPrev.grey:hover, #lbPrev.grey:visited:hover { background: url(images/prev_grey.gif) left 15% no-repeat; }\r
+ #lbPrev.red:hover, #lbPrev.red:visited:hover { background: url(images/prev_red.gif) left 15% no-repeat; }\r
+ #lbPrev.green:hover, #lbPrev.green:visited:hover { background: url(images/prev_green.gif) left 15% no-repeat; }\r
+ #lbPrev.blue:hover, #lbPrev.blue:visited:hover { background: url(images/prev_blue.gif) left 15% no-repeat; }\r
+ #lbPrev.gold:hover, #lbPrev.gold:visited:hover { background: url(images/prev_gold.gif) left 15% no-repeat; }\r
+ \r
+#lbNext { width: 49%; height: 100%; background: transparent url(images/blank.gif) no-repeat; display: block; right: 0; float: right; }\r
+ #lbNext.grey:hover, #lbNext.grey:visited:hover { background: url(images/next_grey.gif) right 15% no-repeat; }\r
+ #lbNext.red:hover, #lbNext.red:visited:hover { background: url(images/next_red.gif) right 15% no-repeat; }\r
+ #lbNext.green:hover, #lbNext.green:visited:hover { background: url(images/next_green.gif) right 15% no-repeat; }\r
+ #lbNext.blue:hover, #lbNext.blue:visited:hover { background: url(images/next_blue.gif) right 15% no-repeat; }\r
+ #lbNext.gold:hover, #lbNext.gold:visited:hover { background: url(images/next_gold.gif) right 15% no-repeat; }\r
+\r
+#lbPrev2, #lbNext2 { text-decoration: none; font-weight: bold; }\r
+ #lbPrev2.grey, #lbNext2.grey, #lbSpacer.grey { color: #333333; }\r
+ #lbPrev2.red, #lbNext2.red, #lbSpacer.red { color: #620000; }\r
+ #lbPrev2.green, #lbNext2.green, #lbSpacer.green { color: #003300; }\r
+ #lbPrev2.blue, #lbNext2.blue, #lbSpacer.blue { color: #01379E; }\r
+ #lbPrev2.gold, #lbNext2.gold, #lbSpacer.gold { color: #666600; }\r
+ \r
+#lbPrev2_Off, #lbNext2_Off { font-weight: bold; }\r
+ #lbPrev2_Off.grey, #lbNext2_Off.grey { color: #CCCCCC; }\r
+ #lbPrev2_Off.red, #lbNext2_Off.red { color: #FFCCCC; }\r
+ #lbPrev2_Off.green, #lbNext2_Off.green { color: #82FF82; }\r
+ #lbPrev2_Off.blue, #lbNext2_Off.blue { color: #B7CAEE; }\r
+ #lbPrev2_Off.gold, #lbNext2_Off.gold { color: #E1E100; }\r
+ \r
+#lbDetailsData { padding: 0 10px; }\r
+ #lbDetailsData.grey { color: #333333; }\r
+ #lbDetailsData.red { color: #620000; }\r
+ #lbDetailsData.green { color: #003300; }\r
+ #lbDetailsData.blue { color: #01379E; }\r
+ #lbDetailsData.gold { color: #666600; }\r
+\r
+#lbDetails { width: 60%; float: left; text-align: left; }\r
+#lbCaption { display: block; font-weight: bold; }\r
+#lbNumberDisplay { float: left; display: block; padding-bottom: 1.0em; }\r
+#lbNavDisplay { float: left; display: block; padding-bottom: 1.0em; }\r
+\r
+#lbClose { width: 64px; height: 28px; float: right; margin-bottom: 1px; }\r
+ #lbClose.grey { background: url(images/close_grey.png) no-repeat; }\r
+ #lbClose.red { background: url(images/close_red.png) no-repeat; }\r
+ #lbClose.green { background: url(images/close_green.png) no-repeat; }\r
+ #lbClose.blue { background: url(images/close_blue.png) no-repeat; }\r
+ #lbClose.gold { background: url(images/close_gold.png) no-repeat; }\r
+\r
+#lbPlay { width: 64px; height: 28px; float: right; margin-bottom: 1px; }\r
+ #lbPlay.grey { background: url(images/play_grey.png) no-repeat; }\r
+ #lbPlay.red { background: url(images/play_red.png) no-repeat; }\r
+ #lbPlay.green { background: url(images/play_green.png) no-repeat; }\r
+ #lbPlay.blue { background: url(images/play_blue.png) no-repeat; }\r
+ #lbPlay.gold { background: url(images/play_gold.png) no-repeat; }\r
+ \r
+#lbPause { width: 64px; height: 28px; float: right; margin-bottom: 1px; }\r
+ #lbPause.grey { background: url(images/pause_grey.png) no-repeat; }\r
+ #lbPause.red { background: url(images/pause_red.png) no-repeat; }\r
+ #lbPause.green { background: url(images/pause_green.png) no-repeat; }\r
+ #lbPause.blue { background: url(images/pause_blue.png) no-repeat; }\r
+ #lbPause.gold { background: url(images/pause_gold.png) no-repeat; }
\ No newline at end of file
--- /dev/null
+//***********************************************************************************************************************************/\r
+// LyteBox v3.22\r
+//\r
+// Author: Markus F. Hay\r
+// Website: http://www.dolem.com/lytebox\r
+// Date: October 2, 2007\r
+// License: Creative Commons Attribution 3.0 License (http://creativecommons.org/licenses/by/3.0/)\r
+// Browsers: Tested successfully on WinXP with the following browsers (using no DOCTYPE and Strict/Transitional/Loose DOCTYPES):\r
+// * Firefox: 2.0.0.7, 1.5.0.12\r
+// * Internet Explorer: 7.0, 6.0 SP2, 5.5 SP2\r
+// * Opera: 9.23\r
+//\r
+// Releases: For up-to-date and complete release information, visit http://www.dolem.com/forum/showthread.php?tid=62\r
+// * v3.22 (10/02/07)\r
+// * v3.21 (09/30/07)\r
+// * v3.20 (07/12/07)\r
+// * v3.10 (05/28/07)\r
+// * v3.00 (05/15/07)\r
+// * v2.02 (11/13/06)\r
+//\r
+// Credit: LyteBox was originally derived from the Lightbox class (v2.02) that was written by Lokesh Dhakar. For more\r
+// information please visit http://huddletogether.com/projects/lightbox2/\r
+//***********************************************************************************************************************************/\r
+Array.prototype.removeDuplicates = function () { for (var i = 1; i < this.length; i++) { if (this[i][0] == this[i-1][0]) { this.splice(i,1); } } }\r
+Array.prototype.empty = function () { for (var i = 0; i <= this.length; i++) { this.shift(); } }\r
+String.prototype.trim = function () { return this.replace(/^\s+|\s+$/g, ''); }\r
+\r
+function LyteBox() {\r
+ /*** Start Global Configuration ***/\r
+ this.theme = 'grey'; // themes: grey (default), red, green, blue, gold\r
+ this.hideFlash = true; // controls whether or not Flash objects should be hidden\r
+ this.outerBorder = true; // controls whether to show the outer grey (or theme) border\r
+ this.resizeSpeed = 8; // controls the speed of the image resizing (1=slowest and 10=fastest)\r
+ this.maxOpacity = 80; // higher opacity = darker overlay, lower opacity = lighter overlay\r
+ this.navType = 1; // 1 = "Prev/Next" buttons on top left and left (default), 2 = "<< prev | next >>" links next to image number\r
+ this.autoResize = true; // controls whether or not images should be resized if larger than the browser window dimensions\r
+ this.doAnimations = true; // controls whether or not "animate" Lytebox, i.e. resize transition between images, fade in/out effects, etc.\r
+ \r
+ this.borderSize = 12; // if you adjust the padding in the CSS, you will need to update this variable -- otherwise, leave this alone...\r
+ /*** End Global Configuration ***/\r
+ \r
+ /*** Configure Slideshow Options ***/\r
+ this.slideInterval = 4000; // Change value (milliseconds) to increase/decrease the time between "slides" (10000 = 10 seconds)\r
+ this.showNavigation = true; // true to display Next/Prev buttons/text during slideshow, false to hide\r
+ this.showClose = true; // true to display the Close button, false to hide\r
+ this.showDetails = true; // true to display image details (caption, count), false to hide\r
+ this.showPlayPause = true; // true to display pause/play buttons next to close button, false to hide\r
+ this.autoEnd = true; // true to automatically close Lytebox after the last image is reached, false to keep open\r
+ this.pauseOnNextClick = false; // true to pause the slideshow when the "Next" button is clicked\r
+ this.pauseOnPrevClick = true; // true to pause the slideshow when the "Prev" button is clicked\r
+ /*** End Slideshow Configuration ***/\r
+ \r
+ if(this.resizeSpeed > 10) { this.resizeSpeed = 10; }\r
+ if(this.resizeSpeed < 1) { resizeSpeed = 1; }\r
+ this.resizeDuration = (11 - this.resizeSpeed) * 0.15;\r
+ this.resizeWTimerArray = new Array();\r
+ this.resizeWTimerCount = 0;\r
+ this.resizeHTimerArray = new Array();\r
+ this.resizeHTimerCount = 0;\r
+ this.showContentTimerArray = new Array();\r
+ this.showContentTimerCount = 0;\r
+ this.overlayTimerArray = new Array();\r
+ this.overlayTimerCount = 0;\r
+ this.imageTimerArray = new Array();\r
+ this.imageTimerCount = 0;\r
+ this.timerIDArray = new Array();\r
+ this.timerIDCount = 0;\r
+ this.slideshowIDArray = new Array();\r
+ this.slideshowIDCount = 0;\r
+ this.imageArray = new Array();\r
+ this.activeImage = null;\r
+ this.slideArray = new Array();\r
+ this.activeSlide = null;\r
+ this.frameArray = new Array();\r
+ this.activeFrame = null;\r
+ this.checkFrame();\r
+ this.isSlideshow = false;\r
+ this.isLyteframe = false;\r
+ /*@cc_on\r
+ /*@if (@_jscript)\r
+ this.ie = (document.all && !window.opera) ? true : false;\r
+ /*@else @*/\r
+ this.ie = false;\r
+ /*@end\r
+ @*/\r
+ this.ie7 = (this.ie && window.XMLHttpRequest); \r
+ this.initialize();\r
+}\r
+LyteBox.prototype.initialize = function() {\r
+ this.updateLyteboxItems();\r
+ var objBody = this.doc.getElementsByTagName("body").item(0); \r
+ if (this.doc.getElementById('lbOverlay')) {\r
+ objBody.removeChild(this.doc.getElementById("lbOverlay"));\r
+ objBody.removeChild(this.doc.getElementById("lbMain"));\r
+ }\r
+ var objOverlay = this.doc.createElement("div");\r
+ objOverlay.setAttribute('id','lbOverlay');\r
+ objOverlay.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ if ((this.ie && !this.ie7) || (this.ie7 && this.doc.compatMode == 'BackCompat')) {\r
+ objOverlay.style.position = 'absolute';\r
+ }\r
+ objOverlay.style.display = 'none';\r
+ objBody.appendChild(objOverlay);\r
+ var objLytebox = this.doc.createElement("div");\r
+ objLytebox.setAttribute('id','lbMain');\r
+ objLytebox.style.display = 'none';\r
+ objBody.appendChild(objLytebox);\r
+ var objOuterContainer = this.doc.createElement("div");\r
+ objOuterContainer.setAttribute('id','lbOuterContainer');\r
+ objOuterContainer.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ objLytebox.appendChild(objOuterContainer);\r
+ var objIframeContainer = this.doc.createElement("div");\r
+ objIframeContainer.setAttribute('id','lbIframeContainer');\r
+ objIframeContainer.style.display = 'none';\r
+ objOuterContainer.appendChild(objIframeContainer);\r
+ var objIframe = this.doc.createElement("iframe");\r
+ objIframe.setAttribute('id','lbIframe');\r
+ objIframe.setAttribute('name','lbIframe');\r
+ objIframe.style.display = 'none';\r
+ objIframeContainer.appendChild(objIframe);\r
+ var objImageContainer = this.doc.createElement("div");\r
+ objImageContainer.setAttribute('id','lbImageContainer');\r
+ objOuterContainer.appendChild(objImageContainer);\r
+ var objLyteboxImage = this.doc.createElement("img");\r
+ objLyteboxImage.setAttribute('id','lbImage');\r
+ objImageContainer.appendChild(objLyteboxImage);\r
+ var objLoading = this.doc.createElement("div");\r
+ objLoading.setAttribute('id','lbLoading');\r
+ objOuterContainer.appendChild(objLoading);\r
+ var objDetailsContainer = this.doc.createElement("div");\r
+ objDetailsContainer.setAttribute('id','lbDetailsContainer');\r
+ objDetailsContainer.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ objLytebox.appendChild(objDetailsContainer);\r
+ var objDetailsData =this.doc.createElement("div");\r
+ objDetailsData.setAttribute('id','lbDetailsData');\r
+ objDetailsData.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ objDetailsContainer.appendChild(objDetailsData);\r
+ var objDetails = this.doc.createElement("div");\r
+ objDetails.setAttribute('id','lbDetails');\r
+ objDetailsData.appendChild(objDetails);\r
+ var objCaption = this.doc.createElement("span");\r
+ objCaption.setAttribute('id','lbCaption');\r
+ objDetails.appendChild(objCaption);\r
+ var objHoverNav = this.doc.createElement("div");\r
+ objHoverNav.setAttribute('id','lbHoverNav');\r
+ objImageContainer.appendChild(objHoverNav);\r
+ var objBottomNav = this.doc.createElement("div");\r
+ objBottomNav.setAttribute('id','lbBottomNav');\r
+ objDetailsData.appendChild(objBottomNav);\r
+ var objPrev = this.doc.createElement("a");\r
+ objPrev.setAttribute('id','lbPrev');\r
+ objPrev.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ objPrev.setAttribute('href','#');\r
+ objHoverNav.appendChild(objPrev);\r
+ var objNext = this.doc.createElement("a");\r
+ objNext.setAttribute('id','lbNext');\r
+ objNext.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ objNext.setAttribute('href','#');\r
+ objHoverNav.appendChild(objNext);\r
+ var objNumberDisplay = this.doc.createElement("span");\r
+ objNumberDisplay.setAttribute('id','lbNumberDisplay');\r
+ objDetails.appendChild(objNumberDisplay);\r
+ var objNavDisplay = this.doc.createElement("span");\r
+ objNavDisplay.setAttribute('id','lbNavDisplay');\r
+ objNavDisplay.style.display = 'none';\r
+ objDetails.appendChild(objNavDisplay);\r
+ var objClose = this.doc.createElement("a");\r
+ objClose.setAttribute('id','lbClose');\r
+ objClose.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ objClose.setAttribute('href','#');\r
+ objBottomNav.appendChild(objClose);\r
+ var objPause = this.doc.createElement("a");\r
+ objPause.setAttribute('id','lbPause');\r
+ objPause.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ objPause.setAttribute('href','#');\r
+ objPause.style.display = 'none';\r
+ objBottomNav.appendChild(objPause);\r
+ var objPlay = this.doc.createElement("a");\r
+ objPlay.setAttribute('id','lbPlay');\r
+ objPlay.setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ objPlay.setAttribute('href','#');\r
+ objPlay.style.display = 'none';\r
+ objBottomNav.appendChild(objPlay);\r
+};\r
+LyteBox.prototype.updateLyteboxItems = function() { \r
+ var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');\r
+ for (var i = 0; i < anchors.length; i++) {\r
+ var anchor = anchors[i];\r
+ var relAttribute = String(anchor.getAttribute('rel'));\r
+ if (anchor.getAttribute('href')) {\r
+ if (relAttribute.toLowerCase().match('lytebox')) {\r
+ anchor.onclick = function () { myLytebox.start(this, false, false); return false; }\r
+ } else if (relAttribute.toLowerCase().match('lyteshow')) {\r
+ anchor.onclick = function () { myLytebox.start(this, true, false); return false; }\r
+ } else if (relAttribute.toLowerCase().match('lyteframe')) {\r
+ anchor.onclick = function () { myLytebox.start(this, false, true); return false; }\r
+ }\r
+ }\r
+ }\r
+};\r
+LyteBox.prototype.start = function(imageLink, doSlide, doFrame) {\r
+ if (this.ie && !this.ie7) { this.toggleSelects('hide'); }\r
+ if (this.hideFlash) { this.toggleFlash('hide'); }\r
+ this.isLyteframe = (doFrame ? true : false);\r
+ var pageSize = this.getPageSize();\r
+ var objOverlay = this.doc.getElementById('lbOverlay');\r
+ var objBody = this.doc.getElementsByTagName("body").item(0);\r
+ objOverlay.style.height = pageSize[1] + "px";\r
+ objOverlay.style.display = '';\r
+ this.appear('lbOverlay', (this.doAnimations ? 0 : this.maxOpacity));\r
+ var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');\r
+ if (this.isLyteframe) {\r
+ this.frameArray = [];\r
+ this.frameNum = 0;\r
+ if ((imageLink.getAttribute('rel') == 'lyteframe')) {\r
+ var rev = imageLink.getAttribute('rev');\r
+ this.frameArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title'), (rev == null || rev == '' ? 'width: 400px; height: 400px; scrolling: auto;' : rev)));\r
+ } else {\r
+ if (imageLink.getAttribute('rel').indexOf('lyteframe') != -1) {\r
+ for (var i = 0; i < anchors.length; i++) {\r
+ var anchor = anchors[i];\r
+ if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {\r
+ var rev = anchor.getAttribute('rev');\r
+ this.frameArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title'), (rev == null || rev == '' ? 'width: 400px; height: 400px; scrolling: auto;' : rev)));\r
+ }\r
+ }\r
+ this.frameArray.removeDuplicates();\r
+ while(this.frameArray[this.frameNum][0] != imageLink.getAttribute('href')) { this.frameNum++; }\r
+ }\r
+ }\r
+ } else {\r
+ this.imageArray = [];\r
+ this.imageNum = 0;\r
+ this.slideArray = [];\r
+ this.slideNum = 0;\r
+ if ((imageLink.getAttribute('rel') == 'lytebox')) {\r
+ this.imageArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title')));\r
+ } else {\r
+ if (imageLink.getAttribute('rel').indexOf('lytebox') != -1) {\r
+ for (var i = 0; i < anchors.length; i++) {\r
+ var anchor = anchors[i];\r
+ if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {\r
+ this.imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));\r
+ }\r
+ }\r
+ this.imageArray.removeDuplicates();\r
+ while(this.imageArray[this.imageNum][0] != imageLink.getAttribute('href')) { this.imageNum++; }\r
+ }\r
+ if (imageLink.getAttribute('rel').indexOf('lyteshow') != -1) {\r
+ for (var i = 0; i < anchors.length; i++) {\r
+ var anchor = anchors[i];\r
+ if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {\r
+ this.slideArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));\r
+ }\r
+ }\r
+ this.slideArray.removeDuplicates();\r
+ while(this.slideArray[this.slideNum][0] != imageLink.getAttribute('href')) { this.slideNum++; }\r
+ }\r
+ }\r
+ }\r
+ var object = this.doc.getElementById('lbMain');\r
+ object.style.top = (this.getPageScroll() + (pageSize[3] / 15)) + "px";\r
+ object.style.display = '';\r
+ if (!this.outerBorder) {\r
+ this.doc.getElementById('lbOuterContainer').style.border = 'none';\r
+ this.doc.getElementById('lbDetailsContainer').style.border = 'none';\r
+ } else {\r
+ this.doc.getElementById('lbOuterContainer').style.borderBottom = '';\r
+ this.doc.getElementById('lbOuterContainer').setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ }\r
+ this.doc.getElementById('lbOverlay').onclick = function() { myLytebox.end(); return false; }\r
+ this.doc.getElementById('lbMain').onclick = function(e) {\r
+ var e = e;\r
+ if (!e) {\r
+ if (window.parent.frames[window.name] && (parent.document.getElementsByTagName('frameset').length <= 0)) {\r
+ e = window.parent.window.event;\r
+ } else {\r
+ e = window.event;\r
+ }\r
+ }\r
+ var id = (e.target ? e.target.id : e.srcElement.id);\r
+ if (id == 'lbMain') { myLytebox.end(); return false; }\r
+ }\r
+ this.doc.getElementById('lbClose').onclick = function() { myLytebox.end(); return false; }\r
+ this.doc.getElementById('lbPause').onclick = function() { myLytebox.togglePlayPause("lbPause", "lbPlay"); return false; }\r
+ this.doc.getElementById('lbPlay').onclick = function() { myLytebox.togglePlayPause("lbPlay", "lbPause"); return false; } \r
+ this.isSlideshow = doSlide;\r
+ this.isPaused = (this.slideNum != 0 ? true : false);\r
+ if (this.isSlideshow && this.showPlayPause && this.isPaused) {\r
+ this.doc.getElementById('lbPlay').style.display = '';\r
+ this.doc.getElementById('lbPause').style.display = 'none';\r
+ }\r
+ if (this.isLyteframe) {\r
+ this.changeContent(this.frameNum);\r
+ } else {\r
+ if (this.isSlideshow) {\r
+ this.changeContent(this.slideNum);\r
+ } else {\r
+ this.changeContent(this.imageNum);\r
+ }\r
+ }\r
+};\r
+LyteBox.prototype.changeContent = function(imageNum) {\r
+ if (this.isSlideshow) {\r
+ for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }\r
+ }\r
+ this.activeImage = this.activeSlide = this.activeFrame = imageNum;\r
+ if (!this.outerBorder) {\r
+ this.doc.getElementById('lbOuterContainer').style.border = 'none';\r
+ this.doc.getElementById('lbDetailsContainer').style.border = 'none';\r
+ } else {\r
+ this.doc.getElementById('lbOuterContainer').style.borderBottom = '';\r
+ this.doc.getElementById('lbOuterContainer').setAttribute((this.ie ? 'className' : 'class'), this.theme);\r
+ }\r
+ this.doc.getElementById('lbLoading').style.display = '';\r
+ this.doc.getElementById('lbImage').style.display = 'none';\r
+ this.doc.getElementById('lbIframe').style.display = 'none';\r
+ this.doc.getElementById('lbPrev').style.display = 'none';\r
+ this.doc.getElementById('lbNext').style.display = 'none';\r
+ this.doc.getElementById('lbIframeContainer').style.display = 'none';\r
+ this.doc.getElementById('lbDetailsContainer').style.display = 'none';\r
+ this.doc.getElementById('lbNumberDisplay').style.display = 'none';\r
+ if (this.navType == 2 || this.isLyteframe) {\r
+ object = this.doc.getElementById('lbNavDisplay');\r
+ object.innerHTML = ' <span id="lbPrev2_Off" style="display: none;" class="' + this.theme + '">« prev</span><a href="#" id="lbPrev2" class="' + this.theme + '" style="display: none;">« prev</a> <b id="lbSpacer" class="' + this.theme + '">||</b> <span id="lbNext2_Off" style="display: none;" class="' + this.theme + '">next »</span><a href="#" id="lbNext2" class="' + this.theme + '" style="display: none;">next »</a>';\r
+ object.style.display = 'none';\r
+ }\r
+ if (this.isLyteframe) {\r
+ var iframe = myLytebox.doc.getElementById('lbIframe');\r
+ var styles = this.frameArray[this.activeFrame][2];\r
+ var aStyles = styles.split(';');\r
+ for (var i = 0; i < aStyles.length; i++) {\r
+ if (aStyles[i].indexOf('width:') >= 0) {\r
+ var w = aStyles[i].replace('width:', '');\r
+ iframe.width = w.trim();\r
+ } else if (aStyles[i].indexOf('height:') >= 0) {\r
+ var h = aStyles[i].replace('height:', '');\r
+ iframe.height = h.trim();\r
+ } else if (aStyles[i].indexOf('scrolling:') >= 0) {\r
+ var s = aStyles[i].replace('scrolling:', '');\r
+ iframe.scrolling = s.trim();\r
+ } else if (aStyles[i].indexOf('border:') >= 0) {\r
+ // Not implemented yet, as there are cross-platform issues with setting the border (from a GUI standpoint)\r
+ //var b = aStyles[i].replace('border:', '');\r
+ //iframe.style.border = b.trim();\r
+ }\r
+ }\r
+ this.resizeContainer(parseInt(iframe.width), parseInt(iframe.height));\r
+ } else {\r
+ imgPreloader = new Image();\r
+ imgPreloader.onload = function() {\r
+ var imageWidth = imgPreloader.width;\r
+ var imageHeight = imgPreloader.height;\r
+ if (myLytebox.autoResize) {\r
+ var pagesize = myLytebox.getPageSize();\r
+ var x = pagesize[2] - 150;\r
+ var y = pagesize[3] - 150;\r
+ if (imageWidth > x) {\r
+ imageHeight = Math.round(imageHeight * (x / imageWidth));\r
+ imageWidth = x; \r
+ if (imageHeight > y) { \r
+ imageWidth = Math.round(imageWidth * (y / imageHeight));\r
+ imageHeight = y; \r
+ }\r
+ } else if (imageHeight > y) { \r
+ imageWidth = Math.round(imageWidth * (y / imageHeight));\r
+ imageHeight = y; \r
+ if (imageWidth > x) {\r
+ imageHeight = Math.round(imageHeight * (x / imageWidth));\r
+ imageWidth = x;\r
+ }\r
+ }\r
+ }\r
+ var lbImage = myLytebox.doc.getElementById('lbImage')\r
+ lbImage.src = (myLytebox.isSlideshow ? myLytebox.slideArray[myLytebox.activeSlide][0] : myLytebox.imageArray[myLytebox.activeImage][0]);\r
+ lbImage.width = imageWidth;\r
+ lbImage.height = imageHeight;\r
+ myLytebox.resizeContainer(imageWidth, imageHeight);\r
+ imgPreloader.onload = function() {};\r
+ }\r
+ imgPreloader.src = (this.isSlideshow ? this.slideArray[this.activeSlide][0] : this.imageArray[this.activeImage][0]);\r
+ }\r
+};\r
+LyteBox.prototype.resizeContainer = function(imgWidth, imgHeight) {\r
+ this.wCur = this.doc.getElementById('lbOuterContainer').offsetWidth;\r
+ this.hCur = this.doc.getElementById('lbOuterContainer').offsetHeight;\r
+ this.xScale = ((imgWidth + (this.borderSize * 2)) / this.wCur) * 100;\r
+ this.yScale = ((imgHeight + (this.borderSize * 2)) / this.hCur) * 100;\r
+ var wDiff = (this.wCur - this.borderSize * 2) - imgWidth;\r
+ var hDiff = (this.hCur - this.borderSize * 2) - imgHeight;\r
+ if (!(hDiff == 0)) {\r
+ this.hDone = false;\r
+ this.resizeH('lbOuterContainer', this.hCur, imgHeight + this.borderSize*2, this.getPixelRate(this.hCur, imgHeight));\r
+ } else {\r
+ this.hDone = true;\r
+ }\r
+ if (!(wDiff == 0)) {\r
+ this.wDone = false;\r
+ this.resizeW('lbOuterContainer', this.wCur, imgWidth + this.borderSize*2, this.getPixelRate(this.wCur, imgWidth));\r
+ } else {\r
+ this.wDone = true;\r
+ }\r
+ if ((hDiff == 0) && (wDiff == 0)) {\r
+ if (this.ie){ this.pause(250); } else { this.pause(100); } \r
+ }\r
+ this.doc.getElementById('lbPrev').style.height = imgHeight + "px";\r
+ this.doc.getElementById('lbNext').style.height = imgHeight + "px";\r
+ this.doc.getElementById('lbDetailsContainer').style.width = (imgWidth + (this.borderSize * 2) + (this.ie && this.doc.compatMode == "BackCompat" && this.outerBorder ? 2 : 0)) + "px";\r
+ this.showContent();\r
+};\r
+LyteBox.prototype.showContent = function() {\r
+ if (this.wDone && this.hDone) {\r
+ for (var i = 0; i < this.showContentTimerCount; i++) { window.clearTimeout(this.showContentTimerArray[i]); }\r
+ if (this.outerBorder) {\r
+ this.doc.getElementById('lbOuterContainer').style.borderBottom = 'none';\r
+ }\r
+ this.doc.getElementById('lbLoading').style.display = 'none';\r
+ if (this.isLyteframe) {\r
+ this.doc.getElementById('lbIframe').style.display = '';\r
+ this.appear('lbIframe', (this.doAnimations ? 0 : 100));\r
+ } else {\r
+ this.doc.getElementById('lbImage').style.display = '';\r
+ this.appear('lbImage', (this.doAnimations ? 0 : 100));\r
+ this.preloadNeighborImages();\r
+ }\r
+ if (this.isSlideshow) {\r
+ if(this.activeSlide == (this.slideArray.length - 1)) {\r
+ if (this.autoEnd) {\r
+ this.slideshowIDArray[this.slideshowIDCount++] = setTimeout("myLytebox.end('slideshow')", this.slideInterval);\r
+ }\r
+ } else {\r
+ if (!this.isPaused) {\r
+ this.slideshowIDArray[this.slideshowIDCount++] = setTimeout("myLytebox.changeContent("+(this.activeSlide+1)+")", this.slideInterval);\r
+ }\r
+ }\r
+ this.doc.getElementById('lbHoverNav').style.display = (this.showNavigation && this.navType == 1 ? '' : 'none');\r
+ this.doc.getElementById('lbClose').style.display = (this.showClose ? '' : 'none');\r
+ this.doc.getElementById('lbDetails').style.display = (this.showDetails ? '' : 'none');\r
+ this.doc.getElementById('lbPause').style.display = (this.showPlayPause && !this.isPaused ? '' : 'none');\r
+ this.doc.getElementById('lbPlay').style.display = (this.showPlayPause && !this.isPaused ? 'none' : '');\r
+ this.doc.getElementById('lbNavDisplay').style.display = (this.showNavigation && this.navType == 2 ? '' : 'none');\r
+ } else {\r
+ this.doc.getElementById('lbHoverNav').style.display = (this.navType == 1 && !this.isLyteframe ? '' : 'none');\r
+ if ((this.navType == 2 && !this.isLyteframe && this.imageArray.length > 1) || (this.frameArray.length > 1 && this.isLyteframe)) {\r
+ this.doc.getElementById('lbNavDisplay').style.display = '';\r
+ } else {\r
+ this.doc.getElementById('lbNavDisplay').style.display = 'none';\r
+ }\r
+ this.doc.getElementById('lbClose').style.display = '';\r
+ this.doc.getElementById('lbDetails').style.display = '';\r
+ this.doc.getElementById('lbPause').style.display = 'none';\r
+ this.doc.getElementById('lbPlay').style.display = 'none';\r
+ }\r
+ this.doc.getElementById('lbImageContainer').style.display = (this.isLyteframe ? 'none' : '');\r
+ this.doc.getElementById('lbIframeContainer').style.display = (this.isLyteframe ? '' : 'none');\r
+ try {\r
+ this.doc.getElementById('lbIframe').src = this.frameArray[this.activeFrame][0];\r
+ } catch(e) { }\r
+ } else {\r
+ this.showContentTimerArray[this.showContentTimerCount++] = setTimeout("myLytebox.showContent()", 200);\r
+ }\r
+};\r
+LyteBox.prototype.updateDetails = function() {\r
+ var object = this.doc.getElementById('lbCaption');\r
+ var sTitle = (this.isSlideshow ? this.slideArray[this.activeSlide][1] : (this.isLyteframe ? this.frameArray[this.activeFrame][1] : this.imageArray[this.activeImage][1]));\r
+ object.style.display = '';\r
+ object.innerHTML = (sTitle == null ? '' : sTitle);\r
+ this.updateNav();\r
+ this.doc.getElementById('lbDetailsContainer').style.display = '';\r
+ object = this.doc.getElementById('lbNumberDisplay');\r
+ if (this.isSlideshow && this.slideArray.length > 1) {\r
+ object.style.display = '';\r
+ object.innerHTML = "Image " + eval(this.activeSlide + 1) + " of " + this.slideArray.length;\r
+ this.doc.getElementById('lbNavDisplay').style.display = (this.navType == 2 && this.showNavigation ? '' : 'none');\r
+ } else if (this.imageArray.length > 1 && !this.isLyteframe) {\r
+ object.style.display = '';\r
+ object.innerHTML = "Image " + eval(this.activeImage + 1) + " of " + this.imageArray.length;\r
+ this.doc.getElementById('lbNavDisplay').style.display = (this.navType == 2 ? '' : 'none');\r
+ } else if (this.frameArray.length > 1 && this.isLyteframe) {\r
+ object.style.display = '';\r
+ object.innerHTML = "Page " + eval(this.activeFrame + 1) + " of " + this.frameArray.length;\r
+ this.doc.getElementById('lbNavDisplay').style.display = '';\r
+ } else {\r
+ this.doc.getElementById('lbNavDisplay').style.display = 'none';\r
+ }\r
+ this.appear('lbDetailsContainer', (this.doAnimations ? 0 : 100));\r
+};\r
+LyteBox.prototype.updateNav = function() {\r
+ if (this.isSlideshow) {\r
+ if (this.activeSlide != 0) {\r
+ var object = (this.navType == 2 ? this.doc.getElementById('lbPrev2') : this.doc.getElementById('lbPrev'));\r
+ object.style.display = '';\r
+ object.onclick = function() {\r
+ if (myLytebox.pauseOnPrevClick) { myLytebox.togglePlayPause("lbPause", "lbPlay"); }\r
+ myLytebox.changeContent(myLytebox.activeSlide - 1); return false;\r
+ }\r
+ } else {\r
+ if (this.navType == 2) { this.doc.getElementById('lbPrev2_Off').style.display = ''; }\r
+ }\r
+ if (this.activeSlide != (this.slideArray.length - 1)) {\r
+ var object = (this.navType == 2 ? this.doc.getElementById('lbNext2') : this.doc.getElementById('lbNext'));\r
+ object.style.display = '';\r
+ object.onclick = function() {\r
+ if (myLytebox.pauseOnNextClick) { myLytebox.togglePlayPause("lbPause", "lbPlay"); }\r
+ myLytebox.changeContent(myLytebox.activeSlide + 1); return false;\r
+ }\r
+ } else {\r
+ if (this.navType == 2) { this.doc.getElementById('lbNext2_Off').style.display = ''; }\r
+ }\r
+ } else if (this.isLyteframe) {\r
+ if(this.activeFrame != 0) {\r
+ var object = this.doc.getElementById('lbPrev2');\r
+ object.style.display = '';\r
+ object.onclick = function() {\r
+ myLytebox.changeContent(myLytebox.activeFrame - 1); return false;\r
+ }\r
+ } else {\r
+ this.doc.getElementById('lbPrev2_Off').style.display = '';\r
+ }\r
+ if(this.activeFrame != (this.frameArray.length - 1)) {\r
+ var object = this.doc.getElementById('lbNext2');\r
+ object.style.display = '';\r
+ object.onclick = function() {\r
+ myLytebox.changeContent(myLytebox.activeFrame + 1); return false;\r
+ }\r
+ } else {\r
+ this.doc.getElementById('lbNext2_Off').style.display = '';\r
+ } \r
+ } else {\r
+ if(this.activeImage != 0) {\r
+ var object = (this.navType == 2 ? this.doc.getElementById('lbPrev2') : this.doc.getElementById('lbPrev'));\r
+ object.style.display = '';\r
+ object.onclick = function() {\r
+ myLytebox.changeContent(myLytebox.activeImage - 1); return false;\r
+ }\r
+ } else {\r
+ if (this.navType == 2) { this.doc.getElementById('lbPrev2_Off').style.display = ''; }\r
+ }\r
+ if(this.activeImage != (this.imageArray.length - 1)) {\r
+ var object = (this.navType == 2 ? this.doc.getElementById('lbNext2') : this.doc.getElementById('lbNext'));\r
+ object.style.display = '';\r
+ object.onclick = function() {\r
+ myLytebox.changeContent(myLytebox.activeImage + 1); return false;\r
+ }\r
+ } else {\r
+ if (this.navType == 2) { this.doc.getElementById('lbNext2_Off').style.display = ''; }\r
+ }\r
+ }\r
+ this.enableKeyboardNav();\r
+};\r
+LyteBox.prototype.enableKeyboardNav = function() { document.onkeydown = this.keyboardAction; };\r
+LyteBox.prototype.disableKeyboardNav = function() { document.onkeydown = ''; };\r
+LyteBox.prototype.keyboardAction = function(e) {\r
+ var keycode = key = escape = null;\r
+ keycode = (e == null) ? event.keyCode : e.which;\r
+ key = String.fromCharCode(keycode).toLowerCase();\r
+ escape = (e == null) ? 27 : e.DOM_VK_ESCAPE;\r
+ if ((key == 'x') || (key == 'c') || (keycode == escape)) {\r
+ myLytebox.end();\r
+ } else if ((key == 'p') || (keycode == 37)) {\r
+ if (myLytebox.isSlideshow) {\r
+ if(myLytebox.activeSlide != 0) {\r
+ myLytebox.disableKeyboardNav();\r
+ myLytebox.changeContent(myLytebox.activeSlide - 1);\r
+ }\r
+ } else if (myLytebox.isLyteframe) {\r
+ if(myLytebox.activeFrame != 0) {\r
+ myLytebox.disableKeyboardNav();\r
+ myLytebox.changeContent(myLytebox.activeFrame - 1);\r
+ }\r
+ } else {\r
+ if(myLytebox.activeImage != 0) {\r
+ myLytebox.disableKeyboardNav();\r
+ myLytebox.changeContent(myLytebox.activeImage - 1);\r
+ }\r
+ }\r
+ } else if ((key == 'n') || (keycode == 39)) {\r
+ if (myLytebox.isSlideshow) {\r
+ if(myLytebox.activeSlide != (myLytebox.slideArray.length - 1)) {\r
+ myLytebox.disableKeyboardNav();\r
+ myLytebox.changeContent(myLytebox.activeSlide + 1);\r
+ }\r
+ } else if (myLytebox.isLyteframe) {\r
+ if(myLytebox.activeFrame != (myLytebox.frameArray.length - 1)) {\r
+ myLytebox.disableKeyboardNav();\r
+ myLytebox.changeContent(myLytebox.activeFrame + 1);\r
+ }\r
+ } else {\r
+ if(myLytebox.activeImage != (myLytebox.imageArray.length - 1)) {\r
+ myLytebox.disableKeyboardNav();\r
+ myLytebox.changeContent(myLytebox.activeImage + 1);\r
+ }\r
+ }\r
+ }\r
+};\r
+LyteBox.prototype.preloadNeighborImages = function() {\r
+ if (this.isSlideshow) {\r
+ if ((this.slideArray.length - 1) > this.activeSlide) {\r
+ preloadNextImage = new Image();\r
+ preloadNextImage.src = this.slideArray[this.activeSlide + 1][0];\r
+ }\r
+ if(this.activeSlide > 0) {\r
+ preloadPrevImage = new Image();\r
+ preloadPrevImage.src = this.slideArray[this.activeSlide - 1][0];\r
+ }\r
+ } else {\r
+ if ((this.imageArray.length - 1) > this.activeImage) {\r
+ preloadNextImage = new Image();\r
+ preloadNextImage.src = this.imageArray[this.activeImage + 1][0];\r
+ }\r
+ if(this.activeImage > 0) {\r
+ preloadPrevImage = new Image();\r
+ preloadPrevImage.src = this.imageArray[this.activeImage - 1][0];\r
+ }\r
+ }\r
+};\r
+LyteBox.prototype.togglePlayPause = function(hideID, showID) {\r
+ if (this.isSlideshow && hideID == "lbPause") {\r
+ for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }\r
+ }\r
+ this.doc.getElementById(hideID).style.display = 'none';\r
+ this.doc.getElementById(showID).style.display = '';\r
+ if (hideID == "lbPlay") {\r
+ this.isPaused = false;\r
+ if (this.activeSlide == (this.slideArray.length - 1)) {\r
+ this.end();\r
+ } else {\r
+ this.changeContent(this.activeSlide + 1);\r
+ }\r
+ } else {\r
+ this.isPaused = true;\r
+ }\r
+};\r
+LyteBox.prototype.end = function(caller) {\r
+ var closeClick = (caller == 'slideshow' ? false : true);\r
+ if (this.isSlideshow && this.isPaused && !closeClick) { return; }\r
+ this.disableKeyboardNav();\r
+ this.doc.getElementById('lbMain').style.display = 'none';\r
+ this.fade('lbOverlay', (this.doAnimations ? this.maxOpacity : 0));\r
+ this.toggleSelects('visible');\r
+ if (this.hideFlash) { this.toggleFlash('visible'); }\r
+ if (this.isSlideshow) {\r
+ for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }\r
+ }\r
+ if (this.isLyteframe) {\r
+ this.initialize();\r
+ }\r
+};\r
+LyteBox.prototype.checkFrame = function() {\r
+ if (window.parent.frames[window.name] && (parent.document.getElementsByTagName('frameset').length <= 0)) {\r
+ this.isFrame = true;\r
+ this.lytebox = "window.parent." + window.name + ".myLytebox";\r
+ this.doc = parent.document;\r
+ } else {\r
+ this.isFrame = false;\r
+ this.lytebox = "myLytebox";\r
+ this.doc = document;\r
+ }\r
+};\r
+LyteBox.prototype.getPixelRate = function(cur, img) {\r
+ var diff = (img > cur) ? img - cur : cur - img;\r
+ if (diff >= 0 && diff <= 100) { return 10; }\r
+ if (diff > 100 && diff <= 200) { return 15; }\r
+ if (diff > 200 && diff <= 300) { return 20; }\r
+ if (diff > 300 && diff <= 400) { return 25; }\r
+ if (diff > 400 && diff <= 500) { return 30; }\r
+ if (diff > 500 && diff <= 600) { return 35; }\r
+ if (diff > 600 && diff <= 700) { return 40; }\r
+ if (diff > 700) { return 45; }\r
+};\r
+LyteBox.prototype.appear = function(id, opacity) {\r
+ var object = this.doc.getElementById(id).style;\r
+ object.opacity = (opacity / 100);\r
+ object.MozOpacity = (opacity / 100);\r
+ object.KhtmlOpacity = (opacity / 100);\r
+ object.filter = "alpha(opacity=" + (opacity + 10) + ")";\r
+ if (opacity == 100 && (id == 'lbImage' || id == 'lbIframe')) {\r
+ try { object.removeAttribute("filter"); } catch(e) {} /* Fix added for IE Alpha Opacity Filter bug. */\r
+ this.updateDetails();\r
+ } else if (opacity >= this.maxOpacity && id == 'lbOverlay') {\r
+ for (var i = 0; i < this.overlayTimerCount; i++) { window.clearTimeout(this.overlayTimerArray[i]); }\r
+ return;\r
+ } else if (opacity >= 100 && id == 'lbDetailsContainer') {\r
+ try { object.removeAttribute("filter"); } catch(e) {} /* Fix added for IE Alpha Opacity Filter bug. */\r
+ for (var i = 0; i < this.imageTimerCount; i++) { window.clearTimeout(this.imageTimerArray[i]); }\r
+ this.doc.getElementById('lbOverlay').style.height = this.getPageSize()[1] + "px";\r
+ } else {\r
+ if (id == 'lbOverlay') {\r
+ this.overlayTimerArray[this.overlayTimerCount++] = setTimeout("myLytebox.appear('" + id + "', " + (opacity+20) + ")", 1);\r
+ } else {\r
+ this.imageTimerArray[this.imageTimerCount++] = setTimeout("myLytebox.appear('" + id + "', " + (opacity+10) + ")", 1);\r
+ }\r
+ }\r
+};\r
+LyteBox.prototype.fade = function(id, opacity) {\r
+ var object = this.doc.getElementById(id).style;\r
+ object.opacity = (opacity / 100);\r
+ object.MozOpacity = (opacity / 100);\r
+ object.KhtmlOpacity = (opacity / 100);\r
+ object.filter = "alpha(opacity=" + opacity + ")";\r
+ if (opacity <= 0) {\r
+ try {\r
+ object.display = 'none';\r
+ } catch(err) { }\r
+ } else if (id == 'lbOverlay') {\r
+ this.overlayTimerArray[this.overlayTimerCount++] = setTimeout("myLytebox.fade('" + id + "', " + (opacity-20) + ")", 1);\r
+ } else {\r
+ this.timerIDArray[this.timerIDCount++] = setTimeout("myLytebox.fade('" + id + "', " + (opacity-10) + ")", 1);\r
+ }\r
+};\r
+LyteBox.prototype.resizeW = function(id, curW, maxW, pixelrate, speed) {\r
+ if (!this.hDone) {\r
+ this.resizeWTimerArray[this.resizeWTimerCount++] = setTimeout("myLytebox.resizeW('" + id + "', " + curW + ", " + maxW + ", " + pixelrate + ")", 100);\r
+ return;\r
+ }\r
+ var object = this.doc.getElementById(id);\r
+ var timer = speed ? speed : (this.resizeDuration/2);\r
+ var newW = (this.doAnimations ? curW : maxW);\r
+ object.style.width = (newW) + "px";\r
+ if (newW < maxW) {\r
+ newW += (newW + pixelrate >= maxW) ? (maxW - newW) : pixelrate;\r
+ } else if (newW > maxW) {\r
+ newW -= (newW - pixelrate <= maxW) ? (newW - maxW) : pixelrate;\r
+ }\r
+ this.resizeWTimerArray[this.resizeWTimerCount++] = setTimeout("myLytebox.resizeW('" + id + "', " + newW + ", " + maxW + ", " + pixelrate + ", " + (timer+0.02) + ")", timer+0.02);\r
+ if (parseInt(object.style.width) == maxW) {\r
+ this.wDone = true;\r
+ for (var i = 0; i < this.resizeWTimerCount; i++) { window.clearTimeout(this.resizeWTimerArray[i]); }\r
+ }\r
+};\r
+LyteBox.prototype.resizeH = function(id, curH, maxH, pixelrate, speed) {\r
+ var timer = speed ? speed : (this.resizeDuration/2);\r
+ var object = this.doc.getElementById(id);\r
+ var newH = (this.doAnimations ? curH : maxH);\r
+ object.style.height = (newH) + "px";\r
+ if (newH < maxH) {\r
+ newH += (newH + pixelrate >= maxH) ? (maxH - newH) : pixelrate;\r
+ } else if (newH > maxH) {\r
+ newH -= (newH - pixelrate <= maxH) ? (newH - maxH) : pixelrate;\r
+ }\r
+ this.resizeHTimerArray[this.resizeHTimerCount++] = setTimeout("myLytebox.resizeH('" + id + "', " + newH + ", " + maxH + ", " + pixelrate + ", " + (timer+.02) + ")", timer+.02);\r
+ if (parseInt(object.style.height) == maxH) {\r
+ this.hDone = true;\r
+ for (var i = 0; i < this.resizeHTimerCount; i++) { window.clearTimeout(this.resizeHTimerArray[i]); }\r
+ }\r
+};\r
+LyteBox.prototype.getPageScroll = function() {\r
+ if (self.pageYOffset) {\r
+ return this.isFrame ? parent.pageYOffset : self.pageYOffset;\r
+ } else if (this.doc.documentElement && this.doc.documentElement.scrollTop){\r
+ return this.doc.documentElement.scrollTop;\r
+ } else if (document.body) {\r
+ return this.doc.body.scrollTop;\r
+ }\r
+};\r
+LyteBox.prototype.getPageSize = function() { \r
+ var xScroll, yScroll, windowWidth, windowHeight;\r
+ if (window.innerHeight && window.scrollMaxY) {\r
+ xScroll = this.doc.scrollWidth;\r
+ yScroll = (this.isFrame ? parent.innerHeight : self.innerHeight) + (this.isFrame ? parent.scrollMaxY : self.scrollMaxY);\r
+ } else if (this.doc.body.scrollHeight > this.doc.body.offsetHeight){\r
+ xScroll = this.doc.body.scrollWidth;\r
+ yScroll = this.doc.body.scrollHeight;\r
+ } else {\r
+ xScroll = this.doc.getElementsByTagName("html").item(0).offsetWidth;\r
+ yScroll = this.doc.getElementsByTagName("html").item(0).offsetHeight;\r
+ xScroll = (xScroll < this.doc.body.offsetWidth) ? this.doc.body.offsetWidth : xScroll;\r
+ yScroll = (yScroll < this.doc.body.offsetHeight) ? this.doc.body.offsetHeight : yScroll;\r
+ }\r
+ if (self.innerHeight) {\r
+ windowWidth = (this.isFrame) ? parent.innerWidth : self.innerWidth;\r
+ windowHeight = (this.isFrame) ? parent.innerHeight : self.innerHeight;\r
+ } else if (document.documentElement && document.documentElement.clientHeight) {\r
+ windowWidth = this.doc.documentElement.clientWidth;\r
+ windowHeight = this.doc.documentElement.clientHeight;\r
+ } else if (document.body) {\r
+ windowWidth = this.doc.getElementsByTagName("html").item(0).clientWidth;\r
+ windowHeight = this.doc.getElementsByTagName("html").item(0).clientHeight;\r
+ windowWidth = (windowWidth == 0) ? this.doc.body.clientWidth : windowWidth;\r
+ windowHeight = (windowHeight == 0) ? this.doc.body.clientHeight : windowHeight;\r
+ }\r
+ var pageHeight = (yScroll < windowHeight) ? windowHeight : yScroll;\r
+ var pageWidth = (xScroll < windowWidth) ? windowWidth : xScroll;\r
+ return new Array(pageWidth, pageHeight, windowWidth, windowHeight);\r
+};\r
+LyteBox.prototype.toggleFlash = function(state) {\r
+ var objects = this.doc.getElementsByTagName("object");\r
+ for (var i = 0; i < objects.length; i++) {\r
+ objects[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';\r
+ }\r
+ var embeds = this.doc.getElementsByTagName("embed");\r
+ for (var i = 0; i < embeds.length; i++) {\r
+ embeds[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';\r
+ }\r
+ if (this.isFrame) {\r
+ for (var i = 0; i < parent.frames.length; i++) {\r
+ try {\r
+ objects = parent.frames[i].window.document.getElementsByTagName("object");\r
+ for (var j = 0; j < objects.length; j++) {\r
+ objects[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';\r
+ }\r
+ } catch(e) { }\r
+ try {\r
+ embeds = parent.frames[i].window.document.getElementsByTagName("embed");\r
+ for (var j = 0; j < embeds.length; j++) {\r
+ embeds[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';\r
+ }\r
+ } catch(e) { }\r
+ }\r
+ }\r
+};\r
+LyteBox.prototype.toggleSelects = function(state) {\r
+ var selects = this.doc.getElementsByTagName("select");\r
+ for (var i = 0; i < selects.length; i++ ) {\r
+ selects[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';\r
+ }\r
+ if (this.isFrame) {\r
+ for (var i = 0; i < parent.frames.length; i++) {\r
+ try {\r
+ selects = parent.frames[i].window.document.getElementsByTagName("select");\r
+ for (var j = 0; j < selects.length; j++) {\r
+ selects[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';\r
+ }\r
+ } catch(e) { }\r
+ }\r
+ }\r
+};\r
+LyteBox.prototype.pause = function(numberMillis) {\r
+ var now = new Date();\r
+ var exitTime = now.getTime() + numberMillis;\r
+ while (true) {\r
+ now = new Date();\r
+ if (now.getTime() > exitTime) { return; }\r
+ }\r
+};\r
+if (window.addEventListener) {\r
+ window.addEventListener("load",initLytebox,false);\r
+} else if (window.attachEvent) {\r
+ window.attachEvent("onload",initLytebox);\r
+} else {\r
+ window.onload = function() {initLytebox();}\r
+}\r
+function initLytebox() { myLytebox = new LyteBox(); }
\ No newline at end of file
--- /dev/null
+/* kill defaults */\r
+\r
+html, body, p, ul, dl, li, h1, h2, h3, h4, img {\r
+margin: 0;\r
+padding: 0;\r
+}\r
+\r
+ul {\r
+padding: 10px;\r
+}\r
+\r
+img {\r
+border: 0;\r
+padding: 8;\r
+}\r
+\r
+/* ============= */\r
+p {\r
+ margin-bottom: 20px;\r
+}\r
+\r
+a {\r
+ text-decoration: none;\r
+ color: #4d6399;\r
+}\r
+\r
+a:hover {\r
+ text-decoration: underline;\r
+}\r
+\r
+a:active {\r
+ border: none;\r
+}\r
+\r
+h1 {\r
+ font-size: 24px;\r
+ font-weight: bold;\r
+ margin-top: 23px;\r
+ margin-bottom: 29px;\r
+ text-align: center;\r
+}\r
+\r
+h2 {\r
+ font-size: 16px;\r
+ font-weight: bold;\r
+ margin-top: 23px;\r
+ margin-bottom: 9px;\r
+}\r
+\r
+h3 {\r
+ font-size: 12px;\r
+ font-weight: bold;\r
+ margin-top: 23px;\r
+ margin-bottom: 9px;\r
+}\r
+\r
+body {\r
+ background: url(/pithos/images/background.png);\r
+ font-family: 'Lucida Grande', Verdana, Helvetica, Arial, sans-serif;\r
+ font-size: 12px;\r
+ line-height: 20px;\r
+ color: #222;\r
+ margin: 0px 20px 0px 20px; \r
+ text-align: justify;\r
+}\r
+\r
+table {\r
+ font-family: 'Lucida Grande', Verdana, Helvetica, Arial, sans-serif;\r
+ font-size: 12px;\r
+ font-style: italic;\r
+}\r
+\r
+div.page_main {\r
+ margin-left: 25px;\r
+ margin-right: 25px;\r
+ padding-left: 20px;\r
+ padding-right: 20px;\r
+}\r
+\r
+div.wrapper {\r
+ width: 1024px; \r
+ position: relative; \r
+ background: url(/pithos/images/page_shadow.png) repeat-y;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+}\r
+\r
+div.header{\r
+ width: 1024px;\r
+ position: relative;\r
+ background: url(/pithos/images/header.png) no-repeat;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ padding:15px;\r
+}\r
+\r
+div.footer{\r
+ width: 1024px;\r
+ height: 26px;\r
+ background: url(/pithos/images/bottom.png) no-repeat;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+}\r
+\r
+div.disclaimer {\r
+ background: url(/pithos/images/background.png);\r
+ margin-top: 0;\r
+ text-align: center;\r
+ font-size: 10px;\r
+ padding-bottom: 25px;\r
+ text-decoration: none;\r
+}\r
+\r
+div.image_logo{\r
+ float:left;\r
+ width: 100%; \r
+ padding:0px;\r
+ margin:0px 0px 0px 11px;\r
+}\r
+\r
+div.logo-wrap img {\r
+ padding:0px;\r
+ margin:0px;\r
+ border:none;\r
+}\r
+\r
+p.big {\r
+ font-size: 36px;\r
+ font-weight: bold;\r
+}\r
+\r
+p.blurb {\r
+ width: 70%;\r
+}\r
+\r
+div.error {\r
+ color: #f00;\r
+}\r
--- /dev/null
+/*
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS PUB 180-1
+ * Version 2.1a Copyright Paul Johnston 2000 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
+var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
+function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
+function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
+function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
+function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
+function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha1_vm_test()
+{
+ return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
+}
+
+/*
+ * Calculate the SHA-1 of an array of big-endian words, and a bit length
+ */
+function core_sha1(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << (24 - len % 32);
+ x[((len + 64 >> 9) << 4) + 15] = len;
+
+ var w = Array(80);
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+ var e = -1009589776;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+ var olde = e;
+
+ for(var j = 0; j < 80; j++)
+ {
+ if(j < 16) w[j] = x[i + j];
+ else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
+ var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
+ safe_add(safe_add(e, w[j]), sha1_kt(j)));
+ e = d;
+ d = c;
+ c = rol(b, 30);
+ b = a;
+ a = t;
+ }
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ e = safe_add(e, olde);
+ }
+ return Array(a, b, c, d, e);
+
+}
+
+/*
+ * Perform the appropriate triplet combination function for the current
+ * iteration
+ */
+function sha1_ft(t, b, c, d)
+{
+ if(t < 20) return (b & c) | ((~b) & d);
+ if(t < 40) return b ^ c ^ d;
+ if(t < 60) return (b & c) | (b & d) | (c & d);
+ return b ^ c ^ d;
+}
+
+/*
+ * Determine the appropriate additive constant for the current iteration
+ */
+function sha1_kt(t)
+{
+ return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
+ (t < 60) ? -1894007588 : -899497514;
+}
+
+/*
+ * Calculate the HMAC-SHA1 of a key and some data
+ */
+function core_hmac_sha1(key, data)
+{
+ var bkey = str2binb(key);
+ if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
+ return core_sha1(opad.concat(hash), 512 + 160);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
+
+/*
+ * Convert an 8-bit or 16-bit string to an array of big-endian words
+ * In 8-bit function, characters >255 have their hi-byte silently ignored.
+ */
+function str2binb(str)
+{
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < str.length * chrsz; i += chrsz)
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
+ return bin;
+}
+
+/*
+ * Convert an array of big-endian words to a string
+ */
+function binb2str(bin)
+{
+ var str = "";
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < bin.length * 32; i += chrsz)
+ str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
+ return str;
+}
+
+/*
+ * Convert an array of big-endian words to a hex string.
+ */
+function binb2hex(binarray)
+{
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i++)
+ {
+ str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
+ hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
+ }
+ return str;
+}
+
+/*
+ * Convert an array of big-endian words to a base-64 string
+ */
+function binb2b64(binarray)
+{
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i += 3)
+ {
+ var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16)
+ | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
+ | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+ else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+ }
+ }
+ return str;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app>
+ <error-page>
+ <error-code>
+ 503
+ </error-code>
+ <location>
+ /error503.html
+ </location>
+ </error-page>
+ <error-page>
+ <error-code>
+ 502
+ </error-code>
+ <location>
+ /error502.html
+ </location>
+ </error-page>
+ <error-page>
+ <error-code>
+ 403
+ </error-code>
+ <location>
+ /error403.html
+ </location>
+ </error-page>
+
+ <filter>
+ <filter-name>CacheFilter</filter-name>
+ <filter-class>org.gss_project.gss.server.CacheFilter</filter-class>
+ </filter>
+ <filter-mapping>
+ <filter-name>CacheFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <servlet>
+ <servlet-name>Login</servlet-name>
+ <servlet-class>org.gss_project.gss.server.Login</servlet-class>
+ </servlet>
+ <servlet>
+ <servlet-name>Policy</servlet-name>
+ <servlet-class>org.gss_project.gss.server.Policy</servlet-class>
+ </servlet>
+ <servlet>
+ <servlet-name>Registration</servlet-name>
+ <servlet-class>org.gss_project.gss.server.Registration</servlet-class>
+ </servlet>
+ <servlet>
+ <servlet-name>Invitations</servlet-name>
+ <servlet-class>org.gss_project.gss.server.Invitations</servlet-class>
+ </servlet>
+ <servlet>
+ <servlet-name>CouponHandler</servlet-name>
+ <servlet-class>org.gss_project.gss.server.CouponHandler</servlet-class>
+ </servlet>
+ <servlet>
+ <servlet-name>CouponVerifier</servlet-name>
+ <servlet-class>org.gss_project.gss.server.CouponVerifier</servlet-class>
+ </servlet>
+ <servlet>
+ <servlet-name>NonceIssuer</servlet-name>
+ <servlet-class>org.gss_project.gss.server.NonceIssuer</servlet-class>
+ </servlet>
+ <servlet>
+ <servlet-name>TokenRetriever</servlet-name>
+ <servlet-class>org.gss_project.gss.server.TokenRetriever</servlet-class>
+ </servlet>
+ <servlet>
+ <servlet-name>RESTHandler</servlet-name>
+ <servlet-class>org.gss_project.gss.server.rest.RequestHandler</servlet-class>
+ <init-param>
+ <param-name>input</param-name>
+ <param-value>4096</param-value>
+ </init-param>
+ <init-param>
+ <param-name>output</param-name>
+ <param-value>4096</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Login</servlet-name>
+ <url-pattern>/login</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Policy</servlet-name>
+ <url-pattern>/policy</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Registration</servlet-name>
+ <url-pattern>/register</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Invitations</servlet-name>
+ <url-pattern>/invites</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>CouponHandler</servlet-name>
+ <url-pattern>/coupon</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>CouponVerifier</servlet-name>
+ <url-pattern>/submitCoupon</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>NonceIssuer</servlet-name>
+ <url-pattern>/nonce</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>TokenRetriever</servlet-name>
+ <url-pattern>/token</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>RESTHandler</servlet-name>
+ <url-pattern>/rest/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file