1#!/bin/sh
2
3usage() {
4    echo "Usage:"
5    echo "    $(basename $0) <application-name> [-h|-v] ..."
6    echo ""
7    echo "application-name: valid options are: $(valid_app_options)"
8    echo "-h print this help"
9    echo "-v display PMD's version"
10}
11
12valid_app_options () {
13    echo "pmd, cpd, cpdgui, designer, bgastviewer, designerold, ast-dump"
14}
15
16is_cygwin() {
17    case "$(uname)" in
18        CYGWIN*|MINGW*)
19            readonly cygwin=true
20            ;;
21    esac
22    # OS specific support.  $var _must_ be set to either true or false.
23    if [ -z ${cygwin} ] ; then
24        readonly cygwin=false
25    fi
26}
27
28cygwin_paths() {
29    # For Cygwin, switch paths to Windows format before running java
30    if ${cygwin} ; then
31        [ -n "${JAVA_HOME}" ] && JAVA_HOME=$(cygpath --windows "${JAVA_HOME}")
32        [ -n "${JAVAFX_HOME}" ] && JAVAFX_HOME=$(cygpath --windows "${JAVAFX_HOME}")
33        [ -n "${DIRECTORY}" ] && DIRECTORY=$(cygpath --windows "${DIRECTORY}")
34        classpath=$(cygpath --path --windows "${classpath}")
35    fi
36}
37
38convert_cygwin_vars() {
39    # If cygwin, convert to Unix form before manipulating
40    if ${cygwin} ; then
41        [ -n "${JAVA_HOME}" ] && JAVA_HOME=$(cygpath --unix "${JAVA_HOME}")
42        [ -n "${JAVAFX_HOME}" ] && JAVAFX_HOME=$(cygpath --unix "${JAVAFX_HOME}")
43        [ -n "${CLASSPATH}" ] && CLASSPATH=$(cygpath --path --unix "${CLASSPATH}")
44    fi
45}
46
47java_heapsize_settings() {
48    local heapsize=${HEAPSIZE}
49    case "${heapsize}" in
50        [1-9]*[mgMG])
51            readonly HEAPSIZE="-Xmx${heapsize}"
52            ;;
53        '')
54            ;;
55        *)
56            echo "HEAPSIZE '${HEAPSIZE}' unknown (try: 1024m)"
57            exit 1
58    esac
59}
60
61
62set_lib_dir() {
63  if [ -z ${LIB_DIR} ]; then
64    # Allow for symlinks to this script
65    if [ -L $0 ]; then
66      local script_real_loc=$(readlink "$0")
67    else
68      local script_real_loc=$0
69    fi
70    local script_dir=$(dirname "${script_real_loc}")
71    local cwd="${PWD}"
72
73    cd "${script_dir}/../lib"
74    readonly LIB_DIR=/usr/local/share/java/pmd
75    cd "${cwd}"
76  fi
77}
78
79check_lib_dir() {
80  if [ ! -e "${LIB_DIR}" ]; then
81    echo "The jar directory [${LIB_DIR}] does not exist"
82  fi
83}
84
85 script_exit() {
86    echo $1 >&2
87    exit 1
88}
89
90determine_java_version() {
91    local full_ver=$(java -version 2>&1)
92    # java_ver is eg "18" for java 1.8, "90" for java 9.0, "100" for java 10.0.x
93    readonly java_ver=$(echo $full_ver | sed -n '{
94        # replace early access versions, e.g. 11-ea with 11.0.0
95        s/-ea/.0.0/
96        # replace versions such as 10 with 10.0.0
97        s/version "\([0-9]\{1,\}\)"/version "\1.0.0"/
98        # extract the major and minor parts of the version
99        s/^.* version "\(.*\)\.\(.*\)\..*".*$/\1\2/p
100    }')
101    # java_vendor is either java (oracle) or openjdk
102    readonly java_vendor=$(echo $full_ver | sed -n -e 's/^\(.*\) version .*$/\1/p')
103}
104
105jre_specific_vm_options() {
106  if [ "${APPNAME}" = "designer" ]
107  then
108    options=""
109
110    if [ "$java_ver" -ge 80 ] && [ "$java_ver" -lt 90 ]
111    then
112      # no options needed for java8.
113      options=""
114    elif [ "$java_ver" -ge 90 ] && [ "$java_ver" -lt 110 ] && [ "$java_vendor" = "java" ]
115    then
116      # java9 and java10 from oracle contain javafx as a module
117      # open internal module of javafx to reflection (for our TreeViewWrapper)
118      options="--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED"
119      # The rest here is for RichtextFX
120      options+=" --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED"
121      options+=" --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED"
122      options+=" --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED"
123      options+=" --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED"
124      # Warn of remaining illegal accesses
125      options+=" --illegal-access=warn"
126    elif [ "$java_vendor" = "openjdk" ] || ( [ "$java_vendor" = "java" ] && [ "$java_ver" -ge 110 ] )
127    then
128      # openjdk and java11 from oracle onwards do not contain javafx directly
129      # there are no extra options either - javafx will be added to the classpath without modules
130      options=""
131    fi
132
133    echo $options
134  else
135    echo ""
136  fi
137}
138
139 add_pmd_classpath() {
140    if [ -n "$classpath" ]; then
141        classpath="$classpath:${LIB_DIR}/*"
142    else
143        classpath="${LIB_DIR}/*"
144    fi
145}
146
147 add_openjfx_classpath() {
148  if [ "${APPNAME}" = "designer" ]
149  then
150    if [ "$java_vendor" = "openjdk" ] && [ "$java_ver" -lt 100 ]
151    then
152      script_exit "For openjfx at least java 10 is required"
153    elif [ "$java_vendor" = "openjdk" ] || ( [ "$java_vendor" = "java" ] && [ "$java_ver" -ge 110 ] )
154    then
155      # openjfx is required for openjdk builds and oracle java 11 or later
156      if [ -z "${JAVAFX_HOME}" ]
157      then
158        script_exit "The environment variable JAVAFX_HOME is missing."
159      else
160        if [ -n "$classpath" ]; then
161          classpath="$classpath:${JAVAFX_HOME}/lib/*"
162        else
163          classpath="${JAVAFX_HOME}/lib/*"
164        fi
165      fi
166    fi
167  fi
168}
169
170readonly APPNAME="${1}"
171if [ -z "${APPNAME}" ]; then
172    usage
173    exit 1
174fi
175shift
176
177case "${APPNAME}" in
178  "pmd")
179    readonly CLASSNAME="net.sourceforge.pmd.PMD"
180    ;;
181  "cpd")
182    readonly CLASSNAME="net.sourceforge.pmd.cpd.CPD"
183    ;;
184  "designer")
185    readonly CLASSNAME="net.sourceforge.pmd.util.fxdesigner.DesignerStarter"
186    ;;
187  "designerold")
188    readonly CLASSNAME="net.sourceforge.pmd.util.designer.Designer"
189    ;;
190  "bgastviewer")
191    readonly CLASSNAME="net.sourceforge.pmd.util.viewer.Viewer"
192    ;;
193  "cpdgui")
194    readonly CLASSNAME="net.sourceforge.pmd.cpd.GUI"
195    ;;
196  "ast-dump")
197    readonly CLASSNAME="net.sourceforge.pmd.util.treeexport.TreeExportCli"
198    ;;
199  *)
200    echo "${APPNAME} is NOT a valid application name, valid options are:$(valid_app_options)"
201    ;;
202esac
203
204is_cygwin
205
206set_lib_dir
207check_lib_dir
208
209convert_cygwin_vars
210
211classpath=$CLASSPATH
212
213add_pmd_classpath
214determine_java_version
215add_openjfx_classpath
216
217cygwin_paths
218
219java_heapsize_settings
220
221java ${HEAPSIZE} ${PMD_JAVA_OPTS} $(jre_specific_vm_options) -cp "${classpath}" "${CLASSNAME}" "$@"
222