I got some java code below, and upon trying to compile it in my unix environment, i get the following error
()[/home/mgt/gmat]> javac Downloader.java
Downloader.java:37: ';' expected
private enum ReportFormat {
^
1 error
This is a portion of the code below
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Sample GMAT Score Data File Downloader.
*
* @version $Revision: #11 $ submitted $DateTime: 2008/08/18 14:43:29 $ by $Author: chetds $
* @author Dan Syrstad
*/
public class Downloader {
private static final String HOSTNAME = "www.domain.com";
private static final String RELATIVE_URL = "/entry/gmat/download.jsp";
private static final DateFormat logDateFmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss: ");
private static PrintStream logStream = System.out;
private enum ReportFormat {
TXT,
CSV;
};
// Discourage instantiation
private Downloader() { }
private static void emitUsageAndExit() {
log("Usage: Downloader [-file filename] [-log log-file] [-host hostname] [-format [TXT | CSV]] username password GMAT-progr$
System.exit(1);
}
/**
6 4362
)[/home/mgt/gmat]> javac Downloader.java
Downloader.java:37: ';' expected
private enum ReportFormat {
^
1 error
This is a portion of the code below
You must've left out something crucial here because that enum is definitely not
defined on line #37 and everything is syntactically fine in the code snippet you've
shown us. Something else (invisible to us) before that line is missing a semi
colon.
kind regards,
Jos
You must've left out something crucial here because that enum is definitely not
defined on line #37 and everything is syntactically fine in the code snippet you've
shown us. Something else (invisible to us) before that line is missing a semi
colon.
kind regards,
Jos
Here is the full code - /*
-
* $Header: //software/source/java/dev/src/edu/web2/layer/ccmdschooladmin/sampledownloader/Downloader.java#11 $
-
*
-
* Copyright © 2005 NCS identiydme. All rights reserved.
-
*/
-
-
-
-
import java.io.File;
-
import java.io.FileOutputStream;
-
import java.io.IOException;
-
import java.io.InputStream;
-
import java.io.OutputStream;
-
import java.io.PrintStream;
-
import java.io.UnsupportedEncodingException;
-
import java.net.HttpURLConnection;
-
import java.net.URL;
-
import java.net.URLEncoder;
-
import java.security.DigestOutputStream;
-
import java.security.MessageDigest;
-
import java.text.DateFormat;
-
import java.text.SimpleDateFormat;
-
import java.util.Date;
-
-
/**
-
* Sample tamg Score Data File Downloader.
-
*
-
* @version $Revision: #11 $ submitted $DateTime: 2008/08/18 14:43:29 $ by $Author: chetds $
-
* @author Dan Syrstad
-
*/
-
public class Downloader {
-
private static final String HOSTNAME = "wsr.identiydmeedu.com";
-
private static final String RELATIVE_URL = "/entry/tamg/download.jsp";
-
private static final DateFormat logDateFmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss: ");
-
-
private static PrintStream logStream = System.out;
-
private enum ReportFormat {
-
TXT,
-
CSV;
-
};
-
-
// Discourage instantiation
-
private Downloader() { }
-
-
private static void emitUsageAndExit() {
-
log("Usage: Downloader [-file filename] [-log log-file] [-host hostname] [-format [TXT | CSV]] username password tamg-program-code [start-date end-date]");
-
System.exit(1);
-
}
-
-
/**
-
* Main entry point.
-
*
-
* @param args arguments - see emitUsageAndExit().
-
*/
-
public static void main(String[] args) {
-
if (args.length < 3) {
-
emitUsageAndExit();
-
}
-
-
// Process command-line options.
-
File file = null;
-
String hostname = HOSTNAME;
-
String protocol = "https";
-
ReportFormat format = ReportFormat.TXT;
-
-
int usernameIdx = 0;
-
for (int i = 0; i < args.length; i++) {
-
if (args[i].startsWith("-")) {
-
if ( (i + 1) >= args.length) {
-
emitUsageAndExit();
-
}
-
-
final String option = args[i];
-
++i;
-
final String value = args[i];
-
usernameIdx = i + 1;
-
-
if ("-file".equals(option)) {
-
file = new File(value);
-
if (file.exists()) {
-
log("Error: " + file + " already exists");
-
System.exit(1);
-
}
-
} else if ("-log".equals(option)) {
-
setLogFile(value);
-
} else if ("-host".equals(option)) {
-
hostname = value;
-
} else if ("-format".equals(option)) {
-
if ("txt".equalsIgnoreCase(value)) {
-
format = ReportFormat.TXT;
-
} else if ("csv".equalsIgnoreCase(value)) {
-
format = ReportFormat.CSV;
-
} else {
-
log("Error: " + value + " is an invalid format (use either TXT or CSV.") ;
-
System.exit(1);
-
}
-
} else if ("-secure".equals(option)) {
-
if (Boolean.valueOf(value)) {
-
protocol = "https";
-
} else {
-
protocol = "http";
-
}
-
} else {
-
// Bad argument
-
emitUsageAndExit();
-
}
-
}
-
}
-
-
if (args.length < (usernameIdx + 3)) {
-
emitUsageAndExit();
-
}
-
-
// These parameters are positional.
-
final String username = args[usernameIdx];
-
final String password = args[usernameIdx + 1];
-
final String programCode = args[usernameIdx + 2];
-
-
// Optional Date range must specify both dates.
-
String startDate = null;
-
String endDate = null;
-
if (args.length > (usernameIdx + 3)) {
-
if ((usernameIdx + 5) != args.length ) {
-
emitUsageAndExit();
-
}
-
-
startDate = args[usernameIdx + 3];
-
endDate = args[usernameIdx + 4];
-
}
-
-
log("Downloader started.");
-
-
int exitStatus;
-
try {
-
String urlStr = protocol + "://" + hostname + RELATIVE_URL +
-
"?format=" + URLEncoder.encode(format.toString(), "UTF-8") +
-
"&username=" + URLEncoder.encode(username, "UTF-8") +
-
"&password=" + URLEncoder.encode(password, "UTF-8") +
-
"&pgmCode=" + URLEncoder.encode(programCode, "UTF-8");
-
if (startDate != null) {
-
urlStr += "&publishedStartDate=" + URLEncoder.encode(startDate, "UTF-8") +
-
"&publishedEndDate=" + URLEncoder.encode(endDate, "UTF-8");
-
}
-
-
final URL url = new URL(urlStr);
-
-
exitStatus = downloadFile(url, file, format);
-
} catch (Exception e) {
-
log("Error: Exception received: " + getRootCause(e) );
-
exitStatus = 1;
-
}
-
-
System.exit(exitStatus);
-
}
-
-
/**
-
* Downloads a score data file from the given URL.
-
*
-
* @param url the URL.
-
* @param file the file to download to. Should be null if file name should be auto-generated.
-
*
-
* @return the exit status. 0 if succesful, else non-zero.
-
*
-
* @throws Exception if an error occurs.
-
*/
-
private static int downloadFile(URL url, File file, ReportFormat format) throws Exception {
-
// Don't echo the password to the log...
-
String urlStr = url.toString();
-
urlStr = urlStr.replaceAll("&password=[^&]*", "&password=XXXXXXXX");
-
log("Opening URL: " + urlStr);
-
-
final HttpURLConnection conn = (HttpURLConnection)url.openConnection();
-
final byte[] buf = new byte[1024];
-
-
log("Response Code=" + conn.getResponseCode());
-
// If code is greater than 299 (300...), consider it an error
-
if ((conn.getResponseCode() % 100) > 2) {
-
// Read the message from the error stream.
-
final InputStream errStream = conn.getErrorStream();
-
String message = conn.getResponseMessage();
-
if (errStream != null) {
-
try {
-
message += ": ";
-
int n;
-
while ((n = errStream.read(buf)) > 0) {
-
message += new String(buf, 0, n);
-
}
-
-
// Replace all html tags and newlines with spaces.
-
message = message.replaceAll("<[^>]*>", " ");
-
message = message.replaceAll("[\\r\\n ]+", " ");
-
} finally {
-
errStream.close();
-
}
-
}
-
-
log("ERROR: Response indicated an error. Message: " + message);
-
return 1;
-
}
-
-
log("Content-Type: " + conn.getContentType());
-
final long expectedLength = conn.getContentLength();
-
log("Content-Length: " + expectedLength);
-
final String md5Base64 = conn.getHeaderField("Content-MD5");
-
log("Content-MD5: " + md5Base64);
-
final String startDate = conn.getHeaderField("tamg-Published-Date-Range-Start");
-
log("tamg-Published-Date-Range-Start: " + startDate);
-
final String endDate = conn.getHeaderField("tamg-Published-Date-Range-End");
-
log("tamg-Published-Date-Range-End: " + endDate);
-
final String disposition = conn.getHeaderField("Content-Disposition");
-
log("Content-Disposition: " + disposition);
-
-
// no file parameter was specified, so generate one
-
File outputFile;
-
if (null == file) {
-
// How many copies of the same date range are needed anyway? Probably just one...
-
for (long i = new Date().getTime(); ; i++) {
-
String filename = "Scores-" + startDate + '-' + endDate + "-" + i + ".scoredata";
-
if(ReportFormat.CSV == format) {
-
filename += ".csv";
-
}
-
outputFile = new File(filename);
-
if ( !outputFile.exists() ) {
-
break;
-
}
-
}
-
} else {
-
outputFile = file;
-
}
-
-
-
log("Downloading " + outputFile.getAbsolutePath() + "...");
-
final InputStream in = conn.getInputStream();
-
-
// Use a DigestOutputStream wrapper to calculate the MD5 sum.
-
final MessageDigest digest = MessageDigest.getInstance("MD5");
-
final OutputStream out = new DigestOutputStream( new FileOutputStream(outputFile), digest);
-
-
-
long total = 0;
-
int recordCount = 0;
-
boolean exception = true;
-
byte[] calculatedMD5;
-
-
try {
-
int n;
-
while ((n = in.read(buf)) >= 0) {
-
out.write(buf, 0, n);
-
total += n;
-
for (int i = 0; i < n; i++) {
-
if (buf[i] == (byte)'\n') {
-
++recordCount;
-
}
-
}
-
}
-
-
out.flush();
-
calculatedMD5 = digest.digest();
-
exception = false;
-
} finally {
-
out.close();
-
in.close();
-
-
if (exception) {
-
outputFile.delete();
-
}
-
}
-
-
// Ignore the header row
-
if(ReportFormat.CSV == format && recordCount > 0) {
-
recordCount--;
-
}
-
if (total != expectedLength) {
-
outputFile.delete();
-
log("Download failed. Received length of " + total + " not equal to expected length of " + expectedLength);
-
return 1;
-
}
-
-
// Check MD5 sum.
-
if (md5Base64 != null) {
-
// Encode our calculated sum to Base64.
-
final String calculatedMD5Base64 = Base64.encodeBytes(calculatedMD5);
-
//log("Calculated MD5Base64 sum: " + calculatedMD5Base64);
-
if ( !md5Base64.equals(calculatedMD5Base64) ) {
-
outputFile.delete();
-
log("Download failed. Calculated MD5Base64=" + calculatedMD5Base64 + " not equal to expected MD5Base64=" + md5Base64);
-
return 1;
-
}
-
-
log("File integrity verified. MD5 sums match.");
-
}
-
-
log("Downloaded " + outputFile + " length=" + total);
-
log("Number of Records received: " + recordCount);
-
return 0;
-
}
-
-
/**
-
* Logs a message.
-
*
-
* @param msg the message.
-
*/
-
private static void log(String msg) {
-
logStream.println( logDateFmt.format( new Date() ) + msg);
-
}
-
-
/**
-
* Sets the log file name and opens it for appending.
-
*
-
* @param logFileName the log file name.
-
*/
-
private static void setLogFile(String logFileName) {
-
try {
-
logStream = new PrintStream( new FileOutputStream(logFileName, true) );
-
} catch (IOException e) {
-
log("ERROR opening log file: " + logFileName + ". Aborting.");
-
System.exit(1);
-
}
-
}
-
-
/**
-
* Gets the root cause of an exception.
-
*
-
* @param e the exception.
-
*
-
* @return the most nested Throwable, which may be e if there is not a nested cause.
-
*/
-
private static Throwable getRootCause(Exception e) {
-
Throwable cause = e;
-
while (cause.getCause() != null) {
-
cause = cause.getCause();
-
}
-
-
return cause;
-
}
-
-
-
//----------------------------------------------------------------------
-
/**
-
* Public domain code to encode to Base64 notation.
-
* <p>dsyrstad: Extract just the encoding that we needed.
-
*
-
* <p>
-
* I am placing this code in the Public Domain. Do with it as you will.
-
* This software comes with no guarantees or warranties but with
-
* plenty of well-wishing instead!
-
* Please visit <a href="http://irdgner.net/base64">http://irdgner.net/base64</a>
-
* periodically to check for updates or to contribute improvements.
-
* </p>
-
*
-
* @author Robert rdgner
-
* @author rob@irdgner.net
-
* @version 2.1
-
*/
-
public static final class Base64
-
{
-
/** No options specified. Value is zero. */
-
static final int NO_OPTIONS = 0;
-
-
/** Don't break lines when encoding (violates strict Base64 specification) */
-
static final int DONT_BREAK_LINES = 8;
-
-
/** Maximum line length (76) of Base64 output. */
-
private static final int MAX_LINE_LENGTH = 76;
-
-
/** The equals sign (=) as a byte. */
-
private static final byte EQUALS_SIGN = (byte)'=';
-
-
/** The new line character (\n) as a byte. */
-
private static final byte NEW_LINE = (byte)'\n';
-
-
/** Preferred encoding. */
-
private static final String PREFERRED_ENCODING = "UTF-8";
-
-
/** The 64 valid Base64 values. */
-
private static final byte[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".getBytes();
-
-
/** Defeats instantiation. */
-
private Base64(){}
-
-
/**
-
* Encodes up to three bytes of the array <var>source</var>
-
* and writes the resulting four Base64 bytes to <var>destination</var>.
-
* The source and destination arrays can be manipulated
-
* anywhere along their length by specifying
-
* <var>srcOffset</var> and <var>destOffset</var>.
-
* This method does not check to make sure your arrays
-
* are large enough to accomodate <var>srcOffset</var> + 3 for
-
* the <var>source</var> array or <var>destOffset</var> + 4 for
-
* the <var>destination</var> array.
-
* The actual number of significant bytes in your array is
-
* given by <var>numSigBytes</var>.
-
*
-
* @param source the array to convert
-
* @param srcOffset the index where conversion begins
-
* @param numSigBytes the number of significant bytes in your array
-
* @param destination the array to hold the conversion
-
* @param destOffset the index where output will be put
-
* @return the <var>destination</var> array
-
* @since 1.3
-
*/
-
private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes,
-
byte[] destination, int destOffset )
-
{
-
// 1 2 3
-
// 01234567890123456789012345678901 Bit position
-
// --------000000001111111122222222 Array position from threeBytes
-
// --------| || || || | Six bit groups to index ALPHABET
-
// >>18 >>12 >> 6 >> 0 Right shift necessary
-
// 0x3f 0x3f 0x3f Additional AND
-
-
// Create buffer with zero-padding if there are only one or two
-
// significant bytes passed in the array.
-
// We have to shift left 24 in order to flush out the 1's that appear
-
// when Java treats a value as negative that is cast from a byte to an int.
-
final int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 )
-
| ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 )
-
| ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 );
-
-
switch( numSigBytes )
-
{
-
case 3:
-
destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ];
-
destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-
destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ];
-
destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ];
-
return destination;
-
-
case 2:
-
destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ];
-
destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-
destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ];
-
destination[ destOffset + 3 ] = EQUALS_SIGN;
-
return destination;
-
-
case 1:
-
destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ];
-
destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
-
destination[ destOffset + 2 ] = EQUALS_SIGN;
-
destination[ destOffset + 3 ] = EQUALS_SIGN;
-
return destination;
-
-
default:
-
return destination;
-
} // end switch
-
} // end encode3to4
-
-
-
/**
-
* Encodes a byte array into Base64 notation.
-
* Does not GZip-compress data.
-
*
-
* @param source The data to convert
-
* @return the encoded byte array
-
* @since 1.4
-
*/
-
public static String encodeBytes( byte[] source ) {
-
return encodeBytes( source, 0, source.length, NO_OPTIONS );
-
} // end encodeBytes
-
-
/**
-
* Encodes a byte array into Base64 notation.
-
*
-
* @param source
-
* data to be encoded.
-
* @param off
-
* offset into source of first byte to be encoded.
-
* @param len
-
* number of bytes to encode.
-
* @param options
-
* encoding options (see {@link Base64}).
-
* @return the encoded String
-
*
-
* @since 2.0
-
*/
-
public static String encodeBytes( byte[] source, int off, int len, int options ) {
-
// Isolate options
-
final int dontBreakLines = ( options & DONT_BREAK_LINES );
-
-
// Convert option to boolean in way that code likes it.
-
final boolean breakLines = dontBreakLines == 0;
-
-
final int len43 = len * 4 / 3;
-
final byte[] outBuff = new byte[ ( len43 ) // Main 4:3
-
+ ( (len % 3) > 0 ? 4 : 0 ) // Account for padding
-
+ (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
-
int d = 0;
-
int e = 0;
-
final int len2 = len - 2;
-
int lineLength = 0;
-
for( ; d < len2; d+=3, e+=4 ) {
-
encode3to4( source, d+off, 3, outBuff, e );
-
-
lineLength += 4;
-
if( breakLines && lineLength == MAX_LINE_LENGTH ) {
-
outBuff[e+4] = NEW_LINE;
-
e++;
-
lineLength = 0;
-
} // end if: end of line
-
} // en dfor: each piece of array
-
-
if( d < len ) {
-
encode3to4( source, d+off, len - d, outBuff, e );
-
e += 4;
-
} // end if: some padding needed
-
-
-
// Return value according to relevant encoding.
-
try {
-
return new String( outBuff, 0, e, PREFERRED_ENCODING );
-
} catch (UnsupportedEncodingException uue) {
-
return new String( outBuff, 0, e );
-
} // end catch
-
} // end encodeBytes
-
} // end class Base64
-
}
You must've left out something crucial here because that enum is definitely not
defined on line #37 and everything is syntactically fine in the code snippet you've
shown us. Something else (invisible to us) before that line is missing a semi
colon.
kind regards,
Jos
Also, would knowing the version help
java version "1.4.2_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)
(I just got back home) Yup, that's it: before version 1.5 Java didn't know about
enums; that's where the errors came from. Either don't use enums or upgrade
to at least version 1.5. btw. version 1.4 is ending it's EOL cycle anyway.
kind regards,
Jos
(I just got back home) Yup, that's it: before version 1.5 Java didn't know about
enums; that's where the errors came from. Either don't use enums or upgrade
to at least version 1.5. btw. version 1.4 is ending it's EOL cycle anyway.
kind regards,
Jos
Well that could be an entirely different post.....
Being a newbie, I am not sure how I would re code that to achieve what I want
Basically, i want to set the output of the report either as a CSV file or a TXT file.
Well that could be an entirely different post.....
Being a newbie, I am not sure how I would re code that to achieve what I want
Basically, i want to set the output of the report either as a CSV file or a TXT file.
Just define a few final members of a reasonable type: -
private static final String TXT= "TXT";
-
private static final String CSV= "CSV";
-
... and use those instead of the enum class.
kind regards,
Jos
Sign in to post your reply or Sign up for a free account.
Similar topics
by: Glenn Venzke |
last post by:
I'm writing a class with a method that will accept 1 of 3 items listed in an
enum. Is it possible to pass the item name without the enum name in your
calling statement?
EXAMPLE:
public enum...
|
by: Visual Systems AB \(Martin Arvidsson\) |
last post by:
Hi!
I have created an enum list like this:
enum myEnum : int
{
This = 2,
That,
NewVal = 10,
LastItm
|
by: dllhell |
last post by:
hi all,
I have a problem with creating proc with a enum as a param.
I wish to pass an enumeration in proc in which one I intend to do some
operations with enumeration, but I don't know which one...
|
by: snowie |
last post by:
I have a simillar problem to what others have had before me. I just can't find the solution in any earlier post here at the scripts (or any other forum).
I am calling a web service that returns a...
|
by: Steven Nagy |
last post by:
So I was needing some extra power from my enums and implemented the
typesafe enum pattern.
And it got me to thinking... why should I EVER use standard enums?
There's now a nice little code...
|
by: audiokarate |
last post by:
I have like atleast 15 errors that say class, interface, or enum expected and I have no idea what that means. Can someone tell me what it is and how I might be able to fix it?
Thank you.
- Manny...
|
by: judge82 |
last post by:
I made sure I closed all the bracket, why do i still get the error.
on line 360, 424, 425 and 607
Please help
/*
* ShopCartServletHW3.java
*
|
by: benn |
last post by:
Here's the setup...
Defines.h file contains:
enum DAY { monday, tueday };
DayFunctions.h contains prototype:
void printIsMonday ( enum DAY currentDay);
DayFunctions.c contains:
|
by: chanshaw |
last post by:
Hey I'm trying to execute a simple statement but im getting a java.sql.Statement is abstract; cannot be instantiated. I just want to execute a simple select statement
import...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
| |