Skip to content
Permalink
7a7fcef8ef
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
executable file 293 lines (256 sloc) 9.01 KB
#!/bin/bash
#######################################################################
# Copyright 2016 Internet2
#
# 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.
#######################################################################
#######################################################################
# Help message
#######################################################################
display_help () {
/bin/cat <<- HELP_MSG
This script is a wrapper around the xsltproc command-line tool.
Like xsltproc, this script applies an XSL stylesheet to an XML
document and outputs the resulting transformed document on stdout.
Unlike xsltproc, this script fetches the target XML document
from an HTTP server.
Usage: ${0##*/} [-hv] [-F | -C] [-o OUT_FILE] STYLESHEET URL
This script takes two command-line arguments. The STYLESHEET
argument is the absolute path to an XSL document in the local
file system. The URL argument is the absolute URL of an XML
document. The script fetches the XML document at the given
URL using HTTP Conditional GET [RFC 7232]. If the server
responds with 200, the document in the response body is used.
If the server responds with 304, the document in the cache is
used instead.
This script requires two environment variables. CACHE_DIR is
the absolute path to the cache directory (which may or may not
exist) whereas LIB_DIR specifies a directory containing various
helper scripts.
Options:
-h Display this help message
-v Write verbose messages to stdout
-F Enables "Force Output Mode"
-C Enables "Cache Only Mode"
-o Output the transformed document to OUT_FILE
Option -h is mutually exclusive of all other options.
The default behavior of the script may be modified by using
option -F or -C, which are mutually exclusive. Force Output
Mode (option -F) forces the return of a fresh resource. The
resource is output on stdout if and only if the server
responds with 200. If the response is 304, the script silently
fails with exit code 1.
Cache Only Mode (option -C) bypasses the GET request altogether
and goes directly to cache. If the resource resides in cache,
it is output on stdout, otherwise the script silently fails
with exit code 1.
Option -o specifies an output file in the local file system.
If option -o is omitted, the transformed document is written
to stdout.
LIBRARY
Environment variable LIB_DIR specifies a directory containing at
least the following library files, which act as helper scripts for
${0##*/}:
$LIB_FILENAMES
EXAMPLES
stylesheet=/path/to/stylesheets/style.xsl
url=http://md.incommon.org/InCommon/InCommon-metadata.xml
out_file=/tmp/output.txt
${0##*/} \$stylesheet \$url
${0##*/} -o \$out_file \$stylesheet \$url
${0##*/} -F \$stylesheet \$url
${0##*/} -C \$stylesheet \$url
HELP_MSG
}
#######################################################################
# Bootstrap
#######################################################################
script_name=${0##*/} # equivalent to basename $0
# library filenames
LIB_FILENAMES="core_lib.sh
http_tools.sh"
#######################################################################
# Process command-line options and arguments
#######################################################################
help_mode=false; verbose_mode=false; local_opts=
force_get_mode=false; cache_only_mode=false
while getopts ":hvFCo:" opt; do
case $opt in
h)
help_mode=true
;;
v)
verbose_mode=true
local_opts="$local_opts -$opt"
;;
F)
force_get_mode=true
cache_only_mode=false
local_opts="$local_opts -$opt"
;;
C)
cache_only_mode=true
force_get_mode=false
local_opts="$local_opts -$opt"
;;
o)
out_file="$OPTARG"
;;
\?)
echo "ERROR: $script_name: Unrecognized option: -$OPTARG" >&2
exit 2
;;
:)
echo "ERROR: $script_name: Option -$OPTARG requires an argument" >&2
exit 2
;;
esac
done
if $help_mode; then
display_help
exit 0
fi
# check the output file
if [ -z "$out_file" ]; then
$verbose_mode && echo "$script_name using stdout"
else
$verbose_mode && printf "$script_name using output file: %s\n" "$out_file"
fi
# check the number of remaining arguments
shift $(( OPTIND - 1 ))
if [ "$#" -ne 2 ]; then
echo "ERROR: $script_name found $# command-line arguments (2 required)" >&2
exit 2
fi
# check the stylesheet
xsl_file=$1
if [ ! -f "$xsl_file" ]; then
echo "ERROR: $script_name: file does not exist: $xsl_file" >&2
exit 2
fi
$verbose_mode && printf "$script_name using XSL stylesheet: %s\n" "$xsl_file"
# capture the location of the XML file
xml_location=$2
$verbose_mode && printf "$script_name using XML file at location: %s\n" "$xml_location"
#######################################################################
# Initialization
#######################################################################
# determine the cache directory
if [ -z "$CACHE_DIR" ]; then
echo "ERROR: $script_name requires env var CACHE_DIR" >&2
exit 2
fi
if [ ! -d "$CACHE_DIR" ]; then
/bin/mkdir "$CACHE_DIR"
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $script_name failed to create dir $CACHE_DIR (exit code: $exit_code)" >&2
exit 2
fi
fi
$verbose_mode && printf "$script_name using cache directory: %s\n" "$CACHE_DIR"
# determine the source lib directory
if [ -z "$LIB_DIR" ]; then
echo "ERROR: $script_name requires env var LIB_DIR" >&2
exit 2
fi
if [ ! -d "$LIB_DIR" ]; then
echo "ERROR: $script_name: directory does not exist: $LIB_DIR" >&2
exit 2
fi
$verbose_mode && printf "$script_name using source lib directory: %s\n" "$LIB_DIR"
# source lib files (always source command_paths first)
for lib_filename in $LIB_FILENAMES; do
lib_file="$LIB_DIR/$lib_filename"
if [ ! -f "$lib_file" ]; then
echo "ERROR: $script_name: file does not exist: $lib_file" >&2
exit 2
fi
$verbose_mode && printf "$script_name sourcing lib file: %s\n" "$lib_file"
source "$lib_file" >&2
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $script_name failed to source script $lib_file (exit code: $exit_code)" >&2
exit 2
fi
done
# determine temporary directory
if [ -n "$TMPDIR" ] && [ -d "$TMPDIR" ]; then
# use system temporary directory (remove trailing slash)
TMP_DIR="${TMPDIR%%/}/${script_name%%.*}"
$verbose_mode && printf "$script_name using temp dir: %s\n" "$TMP_DIR"
else
# create temporary directory
tmp_dir="$( make_temp_file -d )"
if [ ! -d "$tmp_dir" ] ; then
printf "ERROR: $script_name unable to create temporary dir\n" >&2
exit 2
fi
# use temporary directory (remove trailing slash)
TMP_DIR="${tmp_dir%%/}/${script_name%%.*}"
$verbose_mode && printf "$script_name creating temp dir: %s\n" "$TMP_DIR"
fi
# create a subdirectory
if [ ! -d "$TMP_DIR" ]; then
/bin/mkdir "$TMP_DIR"
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $script_name failed to create dir $TMP_DIR (exit code: $exit_code)" >&2
exit 2
fi
fi
# temporary files
xml_file="${TMP_DIR}/http_resource_$$.xml"
xsltproc_out_file="${TMP_DIR}/xsltproc_output_$$"
#######################################################################
# Main processing
#######################################################################
# GET the XML document
$verbose_mode && printf "$script_name requesting resource: %s\n" "$xml_location"
conditional_get $local_opts -d "$CACHE_DIR" -T "$TMP_DIR" "$xml_location" > "$xml_file"
exit_code=$?
if [ $exit_code -ne 0 ]; then
if [ $exit_code -gt 1 ]; then
echo "ERROR: $script_name failed to get resource: $location" >&2
printf "See output log: %s\n" "$TMP_DIR/$conditional_get_log" >&2
fi
exit $exit_code
fi
$verbose_mode && printf "$script_name successfully obtained XML file: %s\n" "$xml_file"
# transform the XML document
$verbose_mode && printf "$script_name writing xsltproc output to file: %s\n" "$xsltproc_out_file"
/usr/bin/xsltproc --output "$xsltproc_out_file" "$xsl_file" "$xml_file"
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: ${script_name}: xsltproc failed with status code: $exit_code" >&2
exit 3
fi
$verbose_mode && printf "$script_name successfully executed xsltproc\n"
# output the transformed document
if [ -z "$out_file" ]; then
/bin/cat "$xsltproc_out_file"
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: ${script_name} unable to cat output with status code: $exit_code" >&2
exit 3
fi
else
$verbose_mode && printf "$script_name writing output to file: %s\n" "$out_file"
/bin/cp "$xsltproc_out_file" "$out_file"
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: ${script_name} unable to copy output to file $out_file (exit code: $exit_code)" >&2
exit 3
fi
fi
exit 0