Saturday, May 28, 2005

Reading Date in Excel

We can use Jakarta COMMON POI to do it:

E.g. of Itertate over a file:

// load the excel
FileInputStream fin = new FileInputStream("simple1.xls");
POIFSFileSystem fs = new POIFSFileSystem(fin);
//create a Workbook
HSSFWorkbook wb = new HSSFWorkbook(fs);

// get a reference to the worksheet
int numberPage = wb.getNumberOfSheets();
// TODO:debug information
out.printf("Number Of Page %s%n", numberPage);

//read each sheet
for (int i = 0; i < numberPage; ++i) {
HSSFSheet sheet = wb.getSheetAt(i);

// TODO:debug information
int firstRow = sheet.getFirstRowNum();
int lastRow = sheet.getLastRowNum();
out.printf("FirstRow: %s, LastRow: %s%n", firstRow, lastRow);
out.printf("Physical Row: %s%n", sheet.getPhysicalNumberOfRows());

//read each Row
for (int j = firstRow; j <= lastRow; ++j) {
HSSFRow row = sheet.getRow(j);

//read each Cell
for (short k = row.getFirstCellNum(); k < row.getLastCellNum(); ++k) {
HSSFCell cell = (HSSFCell) row.getCell(k);

switch (cell.getCellType()) {

case (HSSFCell.CELL_TYPE_STRING): {
out.print(cell.getStringCellValue() + "\t");
break;
}

case (HSSFCell.CELL_TYPE_NUMERIC): {
out.print(cell.getNumericCellValue() + "\t");
break;
}

case (HSSFCell.CELL_TYPE_BOOLEAN): {
out.print(cell.getBooleanCellValue() + "\t");
break;
}

}
}
out.println();
}
}
fin.close();

Sunday, May 15, 2005

Security

http://java.sun.com/j2se/1.5.0/docs/api/index.html
http://java.sun.com/j2se/1.5.0/docs/guide/security/doprivileged.html
http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html#DefaultLocs

STill working add more later..

Upload file in a JSP

利用 Oreilly MultiPartRequest 做的範例

http://www.javaworld.com.tw/Old/High/Upload.htm

利用 jspsmart SmartUpload 做的範例

http://www.javaworld.com.tw/Old/High/S_Upload.htm

Jakarta 當然也不能缺席嘛, 來個利用 Jakarta Commons FileUpload 做的範例 Tongue

都是拿 browser 大大的東西來改的, 所以 File.html 拿這裡的就對了 Big Smile

http://www.javaworld.com.tw/Old/High/Upload.htm

也請參閱 jini 葛格的電子報

http://mychannel.pchome.com.tw/channel/class/class_paper_open.htm?d=2003-07-04&e=jakarta&t=.htm&j=17&f=main&v=1

解決了有些瀏覽器會傳送 path + filename 的問題

在電子報這行

// 因為不同的瀏覽器會造成傳遞 path + filename, 有些則只有 filename

註解下就是 jini 葛格加的程式碼

File.jsp (2.36k)

Sunday, May 08, 2005

Call other program in Java

Today some one asked me about calling other porgram in Java. In java 5.0 beside Runtime.exec() we can use the class Process and ProcessBuilder to have a better control on the execute:

ProcessBuilder:
This class is used to create operating system processes.
Note that this class is not synchronized.
When calling the ProcessBuilder().start() we can get a Process object and monitor the output thru it.

Process p = new ProcessBuilder("ping", "localhost").start();
String line = null;
Scanner in = new Scanner(p.getInputStream());
while (in.hasNextLine()) {
line = in.nextLine();
System.out.printf("%s\n", line);
}
Beside when can get the Environment variables by Map ProcessBuilder().environment() and set our own variable to it, usually the values is a copy of the environment of the current process System.getenv() :
PS. o start a process with an explicit set of environment variables, first call Map.clear() before adding environment variables.
 ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
Map env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
pb.directory("myDir");
Process p = pb.start();

Process

It provides Process.getInputStream() and Process.getOutputStream() to read and write data.

Friday, April 29, 2005

Jude Alternative to JavaDoc

Today Computer:

1)Simple Host Authentication for Java (Shaj):
- MS Windows version:
- Unix-like system version:
With this wrapper It is able to write program with authorization function from the Domain Control!!!

Today Focus:

2) Jude:
A replacement to JavaDoc:

Installation:
After downloading you can run:
java -jar jude.jar -autojuice
to generate javadoc data for Jude
However, be remind the following:
1) java file in the above file should be the one of JDK and the src.zip should be in the JDK directory
2) You can Download the SUn's Javadoc file and unzip them in the JDK directory so Jude will have richer Information

Run:
Type the following command in command line or write then to a Batch/Command file
java -jar jude.jar
The Default Listening port is 2009 but you can change it this way:
java -jar jude.jar -port 80
Beside, you can specific the Jude's javadoc data:
java -jar jude.jar myapi.jude

After running, I found the DOS prompt from that execute java is very ugly, and It can't find the java.jude file in its data directory!!! so i wrote my run.bat as below:

Run.bat
javaw -jar "c:\Jude\jude.jar" "c:\Jude\java.jude" -port 80


Then you can close the ugly DOS prompt without closing Jude and able to access Jude by typing "localhost" or "127.0.0.1" in your Mozilia !!!! (of course if you have an apache server you can change port 80 to port 8888 :)

More On JAAS

Someone may unahppy with writting a ungly config to tell JAAS to use which module. However, up to now there is no easy solution to prevent the JAAS config file.....(we can't hard code it into the program anyway).... and itis unpleasent to write a long start command( a lot of maintance work!!)
so my solution is to pass a URL to the class and set the corresponding system property. Although this way is not prefect....(the prefect way it to pass it as a annotation or in a centralic configuration file)... but it look better then typing a long parameters ^_^..


For Example:

NT.config:
NT {
com.tagish.auth.win32.NTSystemLogin required returnNames=true returnSIDs=true defaultDomain="c08913";
};


In the code add this:

URL loginConfigUrl = ClassLoader.getSystemResource("NT.config");
String loginConfigFile = loginConfigUrl.getFile();
System.err.println(loginConfigFile);
System.setProperty("java.security.auth.login.config",
loginConfigFile);
lc = new LoginContext("NT", new MyCallbackHandler());

Eliminate the -Djava.library.path argument in command line for Native Library
Beside, as I tried to pack the natve library into my LoginBeam , So i would like to load the native libraray automatically without specific the native library class path. The System.load() run sucessfully without exception. However, It reported to me that It fail to find the Native library while calling it ........... "Cannot create LoginContext. java.lang.UnsatisfiedLinkError: no NTSystem in java.library.path"

I will investingate it later after the exam......XD

public static void main(String[] args) {
LoginContext lc;
Subject subject = null;

try {
//Load the Native library NTSystem.dll
//-Djava.library.path=C:\Data\eclipse\workspace\NTLoginSystem\bin\lib //load successfully for the native library
URL nativeLib = ClassLoader.getSystemResource("lib/NTSystem.dll");
System.load(nativeLib.getFile());

// find the login config file in the classpath
//Load the NT.config, so we don't need to specific the NT.config at command line
URL loginConfigUrl = ClassLoader.getSystemResource("lib/NT.config");
String loginConfigFile = loginConfigUrl.getFile();
System.setProperty("java.security.auth.login.config",
loginConfigFile);

lc = new LoginContext("NT", new MyCallbackHandler());
lc.login();//Exception here
subject = lc.getSubject();
System.out.println("Login Success");
System.out.println(subject);
} catch (LoginException le) {
System.err
.println("Cannot create LoginContext. " + le.getMessage());
} catch (SecurityException se) {
System.err
.println("Cannot create LoginContext. " + se.getMessage());
}
}





Wednesday, April 27, 2005

JAAS

JavaTM Authentication and Authorization Service (JAAS)
- Sun Offical JAAS Site

- JavaDoc of sun JAAS Package here
- JAAS Tutorial here

After two data investingate.. I found that JAAS is extremely non-user friendly...
Anyway, Here are soem tips and tricks.
First, the NTLoginModule moudle provided by Sun can't allow user to input the domain anme, username and password..... The API takes these information from the underlayer OS and Subject with this input,authenticated and passed on Successfully!!!!!!!!!! If a user can login it's computer he can denfinly pass this test.... So, what is of use of this module...??
I guess it is used for Singel-Sign-On if a user can login their windows their can enjoy the SSO service. What the programers can do is to specify the right principals in the policy and manage the right of differrent group of users!!

If you just want to use the Authentication service from the Domain Controller there still some solutions:

1) Using the NTActiveLoginModule from IBM

Config file setting:
 MyLoginModules {
   com.ibm.security.auth.module.NTActiveLoginModule REQUIRED;
 };
This LoginModule - com.ibm.security.auth.module.NTActiveLoginModule permits using our Callbackhandler. We can then setUsername and setPassword and get it authenticated.

IMPORTANT
http://www-106.ibm.com/developerworks/java/jdk/security/142/secguides/securityg uide.win32.html#wq10

Some forum link that would help:
http://www-106.ibm.com/developerworks/forums/dw_expandTree.jsp?thread=72629& ;forum=178&cat=10&message=12026825#12026825
http://www.mooreds.com/jaas.html
http://www.theserverside.com/blogs/showblog.tss?id=ServletApp
http://java.sun.com/security/jaas/doc/module.html
http://www.ibm.com/developerworks/java/jdk/security/index.html

To make use of this functioanlity, you should have IBM's JDK. Particularly the jaas_activelm.jar, jaas.jar and jaasal.dll . I had Websphere. Hence I got this. I am not sure how to get it otherwise.

2)Using the JAAS Module from Tagish.net

- Tagish Documentation

If you think using IBM JDK is a bit clumbersome or troublesome, you can just download a module from Tagish, However, the update is on 2003/02/17, the library is a bit old but I can still runnning it on my JDK1.5 and MS Windows XP(SR2). The source code is included is downloadable, if everyone can compile it on their compiler!!!

Here is my simple code using Tahish:

Run Command:

java -cp classes -Djava.security.auth.login.config=C:\Data\eclipse\workspace\NTLoginSystem\NT.config -Djava.library.path=C:\Data\eclipse\workspace\NTLoginSystem
Config file Setting:
NTLogin
{
com.tagish.auth.win32.NTSystemLogin required returnNames=true returnSIDs=false defaultDomain="domain";
};

Some Test Code:
Main class:
public class Main {
  public static void main(String[] args) {
      LoginContext lc;
      Subject subject = null;
      try {
          lc = new LoginContext( "NT", new MyCallbackHandler() );
          lc.login();
          subject = lc.getSubject();
    System.out.println("Login Success");
      } catch ( LoginException le ) {
          System.err.println( "Cannot create LoginContext. "
                  + le.getMessage() );
      } catch ( SecurityException se ) {
          System.err.println( "Cannot create LoginContext. "
                  + se.getMessage() );
      }

      System.out.println("Subject: " + subject);
  }
}

MyCallbackHandler class:
class MyCallbackHandler implements CallbackHandler {
public void handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {

for (int i = 0; i <>
if (callbacks[i] instanceof TextOutputCallback) {

// display the message according to the specified type
TextOutputCallback toc = (TextOutputCallback)callbacks[i];
switch (toc.getMessageType()) {
case TextOutputCallback.INFORMATION:
System.out.println(toc.getMessage());
break;
case TextOutputCallback.ERROR:
System.out.println("ERROR: " + toc.getMessage());
break;
case TextOutputCallback.WARNING:
System.out.println("WARNING: " + toc.getMessage());
break;
default:
throw new IOException("Unsupported message type: " +
toc.getMessageType());
}

} else if (callbacks[i] instanceof NameCallback) {

// prompt the user for a username
NameCallback nc = (NameCallback)callbacks[i];

System.err.print(nc.getPrompt());
System.err.flush();
nc.setName((new BufferedReader
(new InputStreamReader(System.in))).readLine());

} else if (callbacks[i] instanceof PasswordCallback) {

// prompt the user for sensitive information
PasswordCallback pc = (PasswordCallback)callbacks[i];
System.err.print(pc.getPrompt());
System.err.flush();
pc.setPassword(readPassword(System.in));

} else {
throw new UnsupportedCallbackException
(callbacks[i], "Unrecognized Callback");
}
}
}

// Reads user password from given input stream.
private char[] readPassword(InputStream in) throws IOException {

char[] lineBuffer;
char[] buf;
int i;

buf = lineBuffer = new char[128];

int room = buf.length;
int offset = 0;
int c;

loop: while (true) {
switch (c = in.read()) {
case -1:
case '\n':
break loop;

case '\r':
int c2 = in.read();
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
} else
break loop;

default:
if (--room <>
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}

if (offset == 0) {
return null;
}

char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');

return ret;
}
}

Result:
Login Success
Subject: 主題:
Principal: NTUserPrincipal: fcmmok [USER]
Principal: NTDomainPrincipal: HPFDCC3 [DOMAIN]
Principal: NTGroupPrincipal: Domain Users [GROUP]
Principal: NTGroupPrincipal: Everyone [GROUP]
Principal: NTGroupPrincipal: Users [GROUP]
Principal: NTGroupPrincipal: Domain Admins [GROUP]
Principal: NTGroupPrincipal: NETWORK [GROUP]
Principal: NTGroupPrincipal: Authenticated Users [GROUP]