Issue #2827 fixed collab dataserver returning empty body with 200
we check if a file exists in and out of the lock when reading if the file is deleted between checks, the inner check attempts to return an error we had already access the output stream from the response object so it is committed to 200 fixed by waiting to get the output stream until after the second check Former-commit-id:ce1038723d
[formerlybfde9c37ce
] [formerlyd44c55e976
[formerly 31c42d161146b0367435c66535d4da700a572f24]] Former-commit-id:d44c55e976
Former-commit-id:d693c07bb4
This commit is contained in:
parent
5b57abd527
commit
ab86cda554
5 changed files with 168 additions and 177 deletions
|
@ -1,168 +1,145 @@
|
||||||
<project default="deploy" basedir=".">
|
<project default="deploy" basedir=".">
|
||||||
|
|
||||||
<property name="workspace" value="${basedir}/../.." />
|
<property name="workspace" value="${basedir}/../.." />
|
||||||
<property name="esb.build.directory" value="${workspace}/edexOsgi/build.edex" />
|
<property name="esb.build.directory" value="${workspace}/edexOsgi/build.edex" />
|
||||||
<property name="feature.file" value="${basedir}.feature/feature.xml"/>
|
<property name="feature.file" value="${basedir}.feature/feature.xml" />
|
||||||
<property name="dataserver.root.directory" value="/awips2/collab-dataserver" />
|
<property name="dataserver.root.directory" value="/awips2/collab-dataserver" />
|
||||||
<property name="includegen.filter" value="raytheon|collaboration.dataserver" />
|
<property name="includegen.filter" value="raytheon|collaboration.dataserver" />
|
||||||
<property name="basedirectories" value="${workspace}/edexOsgi;${workspace}/javaUtilities;${workspace}/cots" />
|
<property name="basedirectories" value="${workspace}/edexOsgi;${workspace}/javaUtilities;${workspace}/cots" />
|
||||||
|
|
||||||
<property name="tmp.dir" value="${basedir}/tmp" />
|
<property name="tmp.dir" value="${basedir}/tmp" />
|
||||||
<property name="includes.directory" value="${tmp.dir}/includes" />
|
<property name="includes.directory" value="${tmp.dir}/includes" />
|
||||||
<property name="tmp.src.dir" value="${tmp.dir}/src" />
|
<property name="tmp.src.dir" value="${tmp.dir}/src" />
|
||||||
<property name="tmp.bin.dir" value="${tmp.dir}/bin" />
|
<property name="tmp.bin.dir" value="${tmp.dir}/bin" />
|
||||||
<property name="tmp.lib.dir" value="${tmp.dir}/lib" />
|
<property name="tmp.lib.dir" value="${tmp.dir}/lib" />
|
||||||
|
|
||||||
<!-- public static final -->
|
<property name="compile.with.debug" value="on" />
|
||||||
<path id="ant.classpath">
|
|
||||||
<fileset dir="${esb.build.directory}/lib/ant">
|
|
||||||
<include name="*.jar" />
|
|
||||||
</fileset>
|
|
||||||
</path>
|
|
||||||
|
|
||||||
<target name="clean" >
|
<!-- public static final -->
|
||||||
<!-- cleanup the temporary directories -->
|
<path id="ant.classpath">
|
||||||
<if>
|
<fileset dir="${esb.build.directory}/lib/ant">
|
||||||
<available file="${basedir}/tmp" type="dir" />
|
<include name="*.jar" />
|
||||||
<then>
|
</fileset>
|
||||||
<delete includeemptydirs="true">
|
</path>
|
||||||
<fileset dir="${basedir}"
|
|
||||||
includes="tmp/**" />
|
|
||||||
</delete>
|
|
||||||
</then>
|
|
||||||
</if>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="clean-dest">
|
<target name="clean">
|
||||||
<!-- clean up the runtime directories -->
|
<!-- cleanup the temporary directories -->
|
||||||
<if>
|
<if>
|
||||||
<available file="${dataserver.root.directory}/lib" />
|
<available file="${basedir}/tmp" type="dir" />
|
||||||
<then>
|
<then>
|
||||||
<delete verbose="true" includeemptydirs="true">
|
<delete includeemptydirs="true">
|
||||||
<fileset dir="${dataserver.root.directory}/lib"
|
<fileset dir="${basedir}" includes="tmp/**" />
|
||||||
includes="*/**"/>
|
</delete>
|
||||||
</delete>
|
</then>
|
||||||
</then>
|
</if>
|
||||||
</if>
|
</target>
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="deploy" depends="clean-dest,build" >
|
<target name="clean-dest">
|
||||||
<mkdir dir="${dataserver.root.directory}/lib/uframe"/>
|
<!-- clean up the runtime directories -->
|
||||||
<!-- jar up dataserver -->
|
<if>
|
||||||
<jar destfile="${dataserver.root.directory}/lib/uframe/collaboration.dataserver.jar" basedir="${tmp.bin.dir}"/>
|
<available file="${dataserver.root.directory}/lib" />
|
||||||
<!-- deploy foss -->
|
<then>
|
||||||
<copy todir="${dataserver.root.directory}/lib/foss" overwrite="true" verbose="true">
|
<delete verbose="true" includeemptydirs="true">
|
||||||
<fileset dir="${tmp.lib.dir}" includes="*.jar"/>
|
<fileset dir="${dataserver.root.directory}/lib" includes="*/**" />
|
||||||
</copy>
|
</delete>
|
||||||
<!-- deploy scripts and config -->
|
</then>
|
||||||
<copy todir="${dataserver.root.directory}/config" overwrite="false" verbose="true">
|
</if>
|
||||||
<fileset dir="${basedir}/config" />
|
</target>
|
||||||
</copy>
|
|
||||||
<copy todir="${dataserver.root.directory}/bin" overwrite="true" verbose="true">
|
|
||||||
<fileset dir="${basedir}/scriptBin" />
|
|
||||||
</copy>
|
|
||||||
<chmod dir="${dataserver.root.directory}/bin" perm="ug+rx" includes="**/*.sh"/>
|
|
||||||
<!-- clean up -->
|
|
||||||
<antcall target="clean"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="build" >
|
<target name="deploy" depends="clean-dest,build">
|
||||||
<sequential>
|
<mkdir dir="${dataserver.root.directory}/lib/uframe" />
|
||||||
<!-- prepare to run includegen -->
|
<!-- jar up dataserver -->
|
||||||
<if>
|
<jar destfile="${dataserver.root.directory}/lib/uframe/collaboration.dataserver.jar" basedir="${tmp.bin.dir}" />
|
||||||
<available file="${includes.directory}" type="dir" />
|
<!-- deploy foss -->
|
||||||
<then>
|
<copy todir="${dataserver.root.directory}/lib/foss" overwrite="true" verbose="true">
|
||||||
<delete verbose="true" includeemptydirs="true">
|
<fileset dir="${tmp.lib.dir}" includes="*.jar" />
|
||||||
<fileset dir="${includes.directory}"
|
</copy>
|
||||||
includes="*/**" />
|
<!-- deploy scripts and config -->
|
||||||
</delete>
|
<copy todir="${dataserver.root.directory}/config" overwrite="false" verbose="true">
|
||||||
</then>
|
<fileset dir="${basedir}/config" />
|
||||||
</if>
|
</copy>
|
||||||
<mkdir dir="${includes.directory}" />
|
<copy todir="${dataserver.root.directory}/bin" overwrite="true" verbose="true">
|
||||||
|
<fileset dir="${basedir}/scriptBin" />
|
||||||
|
</copy>
|
||||||
|
<chmod dir="${dataserver.root.directory}/bin" perm="ug+rx" includes="**/*.sh" />
|
||||||
|
<!-- clean up -->
|
||||||
|
<antcall target="clean" />
|
||||||
|
</target>
|
||||||
|
|
||||||
<!-- run includegen -->
|
<target name="build">
|
||||||
<echo message="Generating deployment list for feature: ${feature}" />
|
<sequential>
|
||||||
|
<!-- prepare to run includegen -->
|
||||||
|
<if>
|
||||||
|
<available file="${includes.directory}" type="dir" />
|
||||||
|
<then>
|
||||||
|
<delete verbose="true" includeemptydirs="true">
|
||||||
|
<fileset dir="${includes.directory}" includes="*/**" />
|
||||||
|
</delete>
|
||||||
|
</then>
|
||||||
|
</if>
|
||||||
|
<mkdir dir="${includes.directory}" />
|
||||||
|
|
||||||
<includegen providerfilter="${includegen.filter}"
|
<!-- run includegen -->
|
||||||
basedirectories="${basedirectories}"
|
<echo message="Generating deployment list for feature: ${feature}" />
|
||||||
featurefile="${feature.file}"
|
|
||||||
cotsout="${includes.directory}/cots.includes"
|
|
||||||
plugsout="${includes.directory}/plugins.includes"
|
|
||||||
coreout="${includes.directory}/core.includes" />
|
|
||||||
|
|
||||||
<!-- copy foss jars to tmp lib folder -->
|
<includegen providerfilter="${includegen.filter}" basedirectories="${basedirectories}" featurefile="${feature.file}" cotsout="${includes.directory}/cots.includes" plugsout="${includes.directory}/plugins.includes" coreout="${includes.directory}/core.includes" />
|
||||||
<copyToBuild includes.file="${includes.directory}/cots.includes"
|
|
||||||
source.base="${workspace}/cots"
|
|
||||||
source.suffix=""
|
|
||||||
includes.pattern="*.jar"
|
|
||||||
target.dir="${tmp.lib.dir}" />
|
|
||||||
|
|
||||||
<!-- copy all uframe source to tmp src folder -->
|
<!-- copy foss jars to tmp lib folder -->
|
||||||
<copyToBuild includes.file="${includes.directory}/core.includes"
|
<copyToBuild includes.file="${includes.directory}/cots.includes" source.base="${workspace}/cots" source.suffix="" includes.pattern="*.jar" target.dir="${tmp.lib.dir}" />
|
||||||
source.base="${workspace}/edexOsgi"
|
|
||||||
source.suffix="src"
|
|
||||||
includes.pattern="**/*.java"
|
|
||||||
target.dir="${tmp.src.dir}" />
|
|
||||||
|
|
||||||
<copyToBuild includes.file="${includes.directory}/plugins.includes"
|
<!-- copy all uframe source to tmp src folder -->
|
||||||
source.base="${workspace}/edexOsgi"
|
<copyToBuild includes.file="${includes.directory}/core.includes" source.base="${workspace}/edexOsgi" source.suffix="src" includes.pattern="**/*.java" target.dir="${tmp.src.dir}" />
|
||||||
source.suffix="src"
|
|
||||||
includes.pattern="**/*.java"
|
|
||||||
target.dir="${tmp.src.dir}" />
|
|
||||||
|
|
||||||
<copy todir="${tmp.src.dir}" overwrite="true" verbose="true">
|
<copyToBuild includes.file="${includes.directory}/plugins.includes" source.base="${workspace}/edexOsgi" source.suffix="src" includes.pattern="**/*.java" target.dir="${tmp.src.dir}" />
|
||||||
<fileset dir="src" includes="**/*.java" />
|
|
||||||
</copy>
|
|
||||||
|
|
||||||
<!-- compile all uframe source at once -->
|
<copy todir="${tmp.src.dir}" overwrite="true" verbose="true">
|
||||||
<path id="foss.path">
|
<fileset dir="src" includes="**/*.java" />
|
||||||
<fileset dir="${tmp.lib.dir}">
|
</copy>
|
||||||
<include name="*.jar"/>
|
|
||||||
</fileset>
|
|
||||||
</path>
|
|
||||||
<mkdir dir="${tmp.bin.dir}" />
|
|
||||||
<javac destdir="${tmp.bin.dir}">
|
|
||||||
<src path="${tmp.src.dir}"/>
|
|
||||||
<classpath refid="foss.path"/>
|
|
||||||
</javac>
|
|
||||||
</sequential>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<!-- iterates over includes file and copies files -->
|
<!-- compile all uframe source at once -->
|
||||||
<macrodef name="copyToBuild">
|
<path id="foss.path">
|
||||||
<attribute name="includes.file"/>
|
<fileset dir="${tmp.lib.dir}">
|
||||||
<attribute name="source.base" />
|
<include name="*.jar" />
|
||||||
<attribute name="source.suffix" />
|
</fileset>
|
||||||
<attribute name="includes.pattern" />
|
</path>
|
||||||
<attribute name="target.dir"/>
|
<mkdir dir="${tmp.bin.dir}" />
|
||||||
|
<javac destdir="${tmp.bin.dir}" debug="${compile.with.debug}">
|
||||||
|
<src path="${tmp.src.dir}" />
|
||||||
|
<classpath refid="foss.path" />
|
||||||
|
</javac>
|
||||||
|
</sequential>
|
||||||
|
</target>
|
||||||
|
|
||||||
<sequential>
|
<!-- iterates over includes file and copies files -->
|
||||||
<echo>@{includes.file}</echo>
|
<macrodef name="copyToBuild">
|
||||||
<loadfile property="@{includes.file}.contents"
|
<attribute name="includes.file" />
|
||||||
srcfile="@{includes.file}" />
|
<attribute name="source.base" />
|
||||||
<for param="line" list="${@{includes.file}.contents}"
|
<attribute name="source.suffix" />
|
||||||
delimiter="${line.separator}">
|
<attribute name="includes.pattern" />
|
||||||
<sequential>
|
<attribute name="target.dir" />
|
||||||
<if>
|
|
||||||
<available file="@{source.base}/@{line}/@{source.suffix}" type="dir" />
|
|
||||||
<then>
|
|
||||||
<copy todir="@{target.dir}" overwrite="true" verbose="true">
|
|
||||||
<fileset dir="@{source.base}/@{line}/@{source.suffix}" includes="@{includes.pattern}" />
|
|
||||||
</copy>
|
|
||||||
</then>
|
|
||||||
<else>
|
|
||||||
<echo>No files found at @{source.base}/@{line}/@{source.suffix}</echo>
|
|
||||||
</else>
|
|
||||||
</if>
|
|
||||||
</sequential>
|
|
||||||
</for>
|
|
||||||
</sequential>
|
|
||||||
</macrodef>
|
|
||||||
|
|
||||||
<!-- static -->
|
<sequential>
|
||||||
<taskdef name="includegen"
|
<echo>@{includes.file}</echo>
|
||||||
classname="com.raytheon.uf.anttasks.includesgen.GenerateIncludesFromFeature"
|
<loadfile property="@{includes.file}.contents" srcfile="@{includes.file}" />
|
||||||
classpathref="ant.classpath" />
|
<for param="line" list="${@{includes.file}.contents}" delimiter="${line.separator}">
|
||||||
<taskdef resource="net/sf/antcontrib/antlib.xml"
|
<sequential>
|
||||||
classpath="${esb.build.directory}/lib/ant/ant-contrib-1.0b3.jar" />
|
<if>
|
||||||
|
<available file="@{source.base}/@{line}/@{source.suffix}" type="dir" />
|
||||||
|
<then>
|
||||||
|
<copy todir="@{target.dir}" overwrite="true" verbose="true">
|
||||||
|
<fileset dir="@{source.base}/@{line}/@{source.suffix}" includes="@{includes.pattern}" />
|
||||||
|
</copy>
|
||||||
|
</then>
|
||||||
|
<else>
|
||||||
|
<echo>No files found at @{source.base}/@{line}/@{source.suffix}</echo>
|
||||||
|
</else>
|
||||||
|
</if>
|
||||||
|
</sequential>
|
||||||
|
</for>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<!-- static -->
|
||||||
|
<taskdef name="includegen" classname="com.raytheon.uf.anttasks.includesgen.GenerateIncludesFromFeature" classpathref="ant.classpath" />
|
||||||
|
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${esb.build.directory}/lib/ant/ant-contrib-1.0b3.jar" />
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -44,7 +43,8 @@ import com.raytheon.uf.common.http.AcceptHeaderValue;
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Feb 5, 2014 2756 bclement Initial creation
|
* Feb 05, 2014 2756 bclement Initial creation
|
||||||
|
* Mar 11, 2014 2827 bclement pass response object to FileManager in doGet
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -113,18 +113,17 @@ public class DataService extends HttpServlet {
|
||||||
throw new RestException(HttpServletResponse.SC_NOT_FOUND,
|
throw new RestException(HttpServletResponse.SC_NOT_FOUND,
|
||||||
"No Such Resource: " + file.getAbsolutePath());
|
"No Such Resource: " + file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
ServletOutputStream out = resp.getOutputStream();
|
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
if (acceptsXml(req)) {
|
if (acceptsXml(req)) {
|
||||||
resp.setContentType(XML_CONTENT_TYPE);
|
resp.setContentType(XML_CONTENT_TYPE);
|
||||||
manager.readDirectoryAsXml(file, out);
|
manager.readDirectoryAsXml(file, resp);
|
||||||
} else {
|
} else {
|
||||||
resp.setContentType(HTML_CONTENT_TYPE);
|
resp.setContentType(HTML_CONTENT_TYPE);
|
||||||
manager.readDirectoryAsHtml(file, out);
|
manager.readDirectoryAsHtml(file, resp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resp.setContentType(BINARY_CONTENT_TYPE);
|
resp.setContentType(BINARY_CONTENT_TYPE);
|
||||||
manager.readFile(file, out);
|
manager.readFile(file, resp);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.warn("Problem handling GET", e);
|
log.warn("Problem handling GET", e);
|
||||||
|
|
|
@ -47,6 +47,7 @@ import com.raytheon.collaboration.dataserver.auth.ServerAuthManager;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Feb 14, 2014 2756 bclement Initial creation
|
* Feb 14, 2014 2756 bclement Initial creation
|
||||||
* Feb 28, 2014 2756 bclement added authManager
|
* Feb 28, 2014 2756 bclement added authManager
|
||||||
|
* Mar 11, 2014 2827 bclement disabled sessions on servlet context handler
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -72,7 +73,7 @@ public class WebServerRunner implements Runnable {
|
||||||
Config.PORT_DEFAULT));
|
Config.PORT_DEFAULT));
|
||||||
|
|
||||||
ServletContextHandler context = new ServletContextHandler(
|
ServletContextHandler context = new ServletContextHandler(
|
||||||
ServletContextHandler.SESSIONS);
|
ServletContextHandler.NO_SESSIONS);
|
||||||
context.setContextPath("/");
|
context.setContextPath("/");
|
||||||
server.setHandler(context);
|
server.setHandler(context);
|
||||||
|
|
||||||
|
@ -84,8 +85,7 @@ public class WebServerRunner implements Runnable {
|
||||||
|
|
||||||
String datapath = Config.getPath(Config.DATAPATH_KEY,
|
String datapath = Config.getPath(Config.DATAPATH_KEY,
|
||||||
Config.DATAPATH_DEFAULT);
|
Config.DATAPATH_DEFAULT);
|
||||||
String pathspec = datapath
|
String pathspec = datapath + "*";
|
||||||
+ "*";
|
|
||||||
context.addServlet(new ServletHolder(new DataService(base)), pathspec);
|
context.addServlet(new ServletHolder(new DataService(base)), pathspec);
|
||||||
|
|
||||||
List<MethodAuthHandler> methods = Arrays.asList(new PutAuthHandler(
|
List<MethodAuthHandler> methods = Arrays.asList(new PutAuthHandler(
|
||||||
|
|
|
@ -50,6 +50,7 @@ import com.raytheon.uf.common.xmpp.iq.SecurityToggleProvider;
|
||||||
* Feb 14, 2014 2756 bclement Initial creation
|
* Feb 14, 2014 2756 bclement Initial creation
|
||||||
* Feb 28, 2014 2756 bclement added custom IQ packet support
|
* Feb 28, 2014 2756 bclement added custom IQ packet support
|
||||||
* Mar 04, 2014 2756 bclement added xmpp server retry
|
* Mar 04, 2014 2756 bclement added xmpp server retry
|
||||||
|
* Mar 11, 2014 2827 bclement changed (dis)connect messages from debug to info
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -97,7 +98,7 @@ public class XmppServerConnection implements Runnable {
|
||||||
registerListeners(conn);
|
registerListeners(conn);
|
||||||
this.conn.connect();
|
this.conn.connect();
|
||||||
this.conn.login(user, password);
|
this.conn.login(user, password);
|
||||||
log.debug("Connected to XMPP server at address: " + xmppServerAddress);
|
log.info("Connected to XMPP server at address: " + xmppServerAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,7 +189,7 @@ public class XmppServerConnection implements Runnable {
|
||||||
* disconnect from XMPP server
|
* disconnect from XMPP server
|
||||||
*/
|
*/
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
log.debug("Disconnecting from XMPP server");
|
log.info("Disconnecting from XMPP server");
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,12 @@ import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import com.raytheon.collaboration.dataserver.RestException;
|
import com.raytheon.collaboration.dataserver.RestException;
|
||||||
|
@ -50,6 +50,7 @@ import com.raytheon.uf.common.util.concurrent.KeyLocker;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Feb 6, 2014 2756 bclement Initial creation
|
* Feb 6, 2014 2756 bclement Initial creation
|
||||||
* Feb 28, 2014 2756 bclement moved to storage package, made buffer size public
|
* Feb 28, 2014 2756 bclement moved to storage package, made buffer size public
|
||||||
|
* Mar 11, 2014 2827 bclement read methods take servlet response object
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -213,31 +214,43 @@ public class FileManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output file to stream
|
* Output file to servlet response
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* @param out
|
* @param resp
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws RestException
|
* @throws RestException
|
||||||
*/
|
*/
|
||||||
public void readFile(File file, OutputStream out) throws IOException,
|
public void readFile(File file, HttpServletResponse resp)
|
||||||
|
throws IOException,
|
||||||
RestException {
|
RestException {
|
||||||
InputStream in = null;
|
InputStream in = null;
|
||||||
List<UsedLock> locks = null;
|
List<UsedLock> locks = null;
|
||||||
|
ServletOutputStream out = null;
|
||||||
try {
|
try {
|
||||||
locks = getReadLocks(file);
|
locks = getReadLocks(file);
|
||||||
if ( !file.exists()){
|
if ( !file.isFile()){
|
||||||
throw new RestException(HttpServletResponse.SC_NOT_FOUND,
|
throw new RestException(HttpServletResponse.SC_NOT_FOUND,
|
||||||
"No Such File: " + file.getAbsoluteFile());
|
"No Such File: " + file.getAbsoluteFile());
|
||||||
}
|
}
|
||||||
in = new FileInputStream(file);
|
in = new FileInputStream(file);
|
||||||
|
/*
|
||||||
|
* We have to wait until we are sure we can read the file before we
|
||||||
|
* get the outputstream. This is because the act of getting the
|
||||||
|
* output stream commits to using it with a 200 response. If we
|
||||||
|
* throw an error, we won't be able to use the response object to
|
||||||
|
* send an error and we will send a 200 with an empty body
|
||||||
|
*/
|
||||||
|
out = resp.getOutputStream();
|
||||||
copy(in, out);
|
copy(in, out);
|
||||||
} finally {
|
} finally {
|
||||||
unlock(locks);
|
unlock(locks);
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
out.close();
|
if (out != null) {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,25 +280,25 @@ public class FileManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output contents of directory to stream in XML format
|
* Output contents of directory to response in XML format
|
||||||
*
|
*
|
||||||
* @param directory
|
* @param directory
|
||||||
* @param out
|
* @param resp
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws RestException
|
* @throws RestException
|
||||||
*/
|
*/
|
||||||
public void readDirectoryAsXml(File directory, OutputStream out)
|
public void readDirectoryAsXml(File directory, HttpServletResponse resp)
|
||||||
throws IOException, RestException {
|
throws IOException, RestException {
|
||||||
List<UsedLock> locks = null;
|
List<UsedLock> locks = null;
|
||||||
Writer w = null;
|
Writer w = null;
|
||||||
try {
|
try {
|
||||||
locks = getReadLocks(directory);
|
locks = getReadLocks(directory);
|
||||||
if (!directory.exists()) {
|
if (!directory.isDirectory()) {
|
||||||
// someone else modified it while waiting for lock
|
// someone else modified it while waiting for lock
|
||||||
throw new RestException(HttpServletResponse.SC_NOT_FOUND,
|
throw new RestException(HttpServletResponse.SC_NOT_FOUND,
|
||||||
"No Such Directory: " + directory.getAbsolutePath());
|
"No Such Directory: " + directory.getAbsolutePath());
|
||||||
}
|
}
|
||||||
w = new OutputStreamWriter(out, "UTF-8");
|
w = resp.getWriter();
|
||||||
w.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
w.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
||||||
w.write("<Contents xmlns=\"urn:uf:viz:collaboration\">");
|
w.write("<Contents xmlns=\"urn:uf:viz:collaboration\">");
|
||||||
for (File f : directory.listFiles()) {
|
for (File f : directory.listFiles()) {
|
||||||
|
@ -325,25 +338,25 @@ public class FileManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output contents of directory to stream in HTML format
|
* Output contents of directory to response in HTML format
|
||||||
*
|
*
|
||||||
* @param directory
|
* @param directory
|
||||||
* @param out
|
* @param resp
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws RestException
|
* @throws RestException
|
||||||
*/
|
*/
|
||||||
public void readDirectoryAsHtml(File directory, OutputStream out)
|
public void readDirectoryAsHtml(File directory, HttpServletResponse resp)
|
||||||
throws IOException, RestException {
|
throws IOException, RestException {
|
||||||
List<UsedLock> locks = null;
|
List<UsedLock> locks = null;
|
||||||
Writer w = null;
|
Writer w = null;
|
||||||
try {
|
try {
|
||||||
locks = getReadLocks(directory);
|
locks = getReadLocks(directory);
|
||||||
if (!directory.exists()) {
|
if (!directory.isDirectory()) {
|
||||||
// someone else modified it while waiting for lock
|
// someone else modified it while waiting for lock
|
||||||
throw new RestException(HttpServletResponse.SC_NOT_FOUND,
|
throw new RestException(HttpServletResponse.SC_NOT_FOUND,
|
||||||
"No Such Directory: " + directory.getAbsolutePath());
|
"No Such Directory: " + directory.getAbsolutePath());
|
||||||
}
|
}
|
||||||
w = new OutputStreamWriter(out, "UTF-8");
|
w = resp.getWriter();
|
||||||
w.write("<!DOCTYPE html>\n");
|
w.write("<!DOCTYPE html>\n");
|
||||||
w.write("<html><body>");
|
w.write("<html><body>");
|
||||||
for (File f : directory.listFiles()) {
|
for (File f : directory.listFiles()) {
|
||||||
|
@ -379,7 +392,7 @@ public class FileManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy bytes from input to output
|
* Copy bytes from input to output. Flushes output after writing.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in
|
||||||
* @param out
|
* @param out
|
||||||
|
@ -392,6 +405,7 @@ public class FileManager {
|
||||||
while ((len = in.read(buff)) != -1) {
|
while ((len = in.read(buff)) != -1) {
|
||||||
out.write(buff, 0, len);
|
out.write(buff, 0, len);
|
||||||
}
|
}
|
||||||
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue