Initial push...

This commit is contained in:
maximstewart 2021-02-20 19:25:30 -06:00
parent 5c13d22216
commit be147b0294
482 changed files with 112377 additions and 0 deletions

File diff suppressed because it is too large Load Diff

BIN
src/Images/Raid Types.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

View File

@ -0,0 +1,102 @@
package eightqueens;
import java.util.Arrays;
import java.util.Random;
public class Algorithm
{
public final int[] lines;
private final Random random;
private final int width, height;
private final int numQueens;
public int firstOffsetX = 0;
public Algorithm(int width, int height)
{
this.width = width;
this.height = height;
numQueens = Math.min(width, height);
lines = new int[height];
Arrays.fill(lines, -1);
random = new Random();
}
public void calculate(int firstX, int firstY)
{
calculate(0, firstX, firstY);
}
private boolean calculate(int row, int firstX, int firstY)
{
// We've reached the bottom of the board
if (row >= numQueens)
{
return true;
}
int seed = random.nextInt(width);
// Loop through the x positions
for (int i = 0; i < width; i++)
{
// Use the seed to create random x values, but only if we are not in the first row,
// so that the first queen's position doesn't change
int x = row == 0 ? i : (i + seed) % width;
// If this position is free, place the queen here
if (isFree(x, row, firstX, firstY))
{
lines[row] = x;
// If the puzzle is solvable for the remaining rows return true,
// else go to the next column
if (calculate(row + 1, firstX, firstY))
{
return true;
} else
{
if (row == 0)
{
firstOffsetX++;
}
lines[row] = -1;
}
}
}
// We've not found a solution, so return false
return false;
}
private boolean isFree(int x, int y, int firstX, int firstY)
{
for (int row = 0; row < height; row++)
{
if (row == y || lines[row] == -1)
{
continue;
}
// If there is a queen above or below, return false
if (lines[row] == x)
{
return false;
}
// Check diagonals
int xx = (x + firstX) % width;
int yy = (y + firstY) % height;
int rrow = (row + firstY) % height;
int heightDifference = Math.abs(rrow - yy);
int widthDifference = Math.abs(((lines[row] + firstX) % width) - xx);
if (widthDifference == heightDifference)
{
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,328 @@
package eightqueens;
import javax.swing.JOptionPane;
import com.rr.Application;
import com.rr.Mouse;
import com.rr.RunConfiguration;
import com.rr.Screen;
import com.rr.core.FBO;
import com.rr.core.Shader;
import com.rr.core.Texture;
import com.rr.core.VAO.DrawMode;
import com.rr.entity.PerspectiveCamera;
import com.rr.graphics.GLState;
import com.rr.graphics.p3d.Model;
import com.rr.math.Calc;
import com.rr.math.Color4;
import com.rr.math.Matrix4;
import com.rr.math.Quaternion;
import com.rr.math.Vector2i;
import com.rr.math.Vector3;
import com.rr.res.Resource;
import com.rr.util.Ray;
public class EightQueens extends Application
{
private static final int WIDTH = 1280;
private static final int HEIGHT = 720;
private static final float BOARD_HEIGHT = 0.0f;
private static final float SENSITIVITY = 10.0f;
private Queen[] queens;
private Texture boardTexture;
private Texture boardHeightmap;
private Model boardFrame;
private Model boardTop;
private FBO queensFBO;
private Texture queensFBOTexture;
private Shader shader;
private Matrix4 projection;
private float cameraDistance;
private float cameraHeight;
private float cameraRotation;
private float lerpedCameraRot;
private float lerpedCameraHeight;
private float lerpedCameraDistance;
private int lastMouseX, lastMouseY;
private Algorithm algorithm;
private int firstX, firstY;
private int boardWidth, boardHeight;
private boolean firstSet = false;
private Thread spawner;
@Override
protected void initApp()
{
try
{
boardWidth = Integer.parseInt(JOptionPane.showInputDialog("Enter the chess board size (must be even!):"));
boardHeight = boardWidth;
} catch (Exception e)
{
JOptionPane.showMessageDialog(null, "Input must be an integer greater than 0.");
System.exit(-1);
}
queens = new Queen[Math.min(boardWidth, boardHeight)];
if (boardWidth <= 3 || boardHeight <= 3)
{
JOptionPane.showMessageDialog(null, "Board size must be bigger than 3 for the puzzle to be solvable.");
System.exit(-1);
}
if (boardWidth % 2 == 1 || boardHeight % 2 == 1)
{
JOptionPane.showMessageDialog(null, "Board size must be even.");
System.exit(-1);
}
JOptionPane.showMessageDialog(null, "Click on a field to set the first queen's position.");
algorithm = new Algorithm(boardWidth, boardHeight);
}
@Override
public void create()
{
GLState.setDepth(true);
GLState.setCulling(true);
GLState.setMultisample(true);
GLState.setClearColor(Color4.BLACK);
boardTexture = Resource.internal.getTexture("/eightqueens/board.png");
boardTexture.setTextureFilter(true, false);
boardHeightmap = Resource.internal.getTexture("/eightqueens/boardHeight.png");
boardHeightmap.setTextureFilter(true, false);
boardFrame = Resource.internal.getModel("/eightqueens/boardFrame.obj").createModel();
boardTop = Resource.internal.getModel("/eightqueens/boardTop.obj").createModel();
shader = Resource.internal.getShader("/eightqueens/diffuse");
projection = Matrix4.perspective(50.0f, 16.0f / 9.0f, 0.1f, 1000.0f);
cameraDistance = 20.0f * Math.max(boardWidth, boardHeight) / 8.0f;
cameraHeight = 40.0f;
cameraRotation = 0.0f;
lastMouseX = Mouse.getX();
lastMouseY = Mouse.getY();
Queen.init();
shader.start();
shader.set("projection", projection);
queensFBO = new FBO(WIDTH, HEIGHT);
queensFBO.bind();
queensFBOTexture = queensFBO.addColorAttachmentTexture(0);
queensFBOTexture.setTextureFilter(true, false);
queensFBO.setDepthAttachmentTexture();
queensFBO.setDepthBuffer(false);
}
@Override
public void fixedUpdate(float dt)
{
int mouseDX = Mouse.getX() - lastMouseX;
int mouseDY = Mouse.getY() - lastMouseY;
lastMouseX = Mouse.getX();
lastMouseY = Mouse.getY();
if (firstSet)
{
cameraDistance -= Mouse.getWheel() * 0.04f;
cameraDistance = Math.max(cameraDistance, 5.0f);
cameraDistance = Math.min(cameraDistance, Math.max(boardWidth, boardHeight) * 10.0f);
if (Mouse.isButtonDown(0))
{
cameraRotation -= mouseDX * dt * SENSITIVITY;
cameraHeight -= mouseDY * dt * SENSITIVITY;
}
}
cameraHeight = Math.max(cameraHeight, -20.0f);
cameraHeight = Math.min(cameraHeight, 88.0f);
lerpedCameraRot = Calc.interpolateLinear(lerpedCameraRot, cameraRotation, 8.0f * dt);
lerpedCameraHeight = Calc.interpolateLinear(lerpedCameraHeight, cameraHeight, 8.0f * dt);
lerpedCameraDistance = Calc.interpolateLinear(lerpedCameraDistance, cameraDistance, 4.0f * dt);
}
@Override
public void update(float dt)
{
if (Mouse.isButtonReleased(0) && !firstSet)
{
Matrix4 cameraM = new Matrix4();
cameraM.translate(0, 0, lerpedCameraDistance);
cameraM.rotate(Vector3.RIGHT, lerpedCameraHeight);
cameraM.rotate(Vector3.UP, lerpedCameraRot);
PerspectiveCamera camera = new PerspectiveCamera(50.0f, 0.1f, 100.0f);
camera.transform.setPosition(cameraM.getTranslation());
camera.transform.setRotation(cameraM.getRotation());
Ray ray = camera.screenPointToRay(new Vector2i(Mouse.getX(), Mouse.getY()));
Vector3 position = ray.origin.rotate(Quaternion.fromEulerAngles(lerpedCameraHeight, lerpedCameraRot, 0));
Vector3 direction = ray.direction;
float distance = -position.y / direction.y;
Vector3 cursorPosition = new Vector3(position.x + distance * direction.x, position.y + distance * direction.y, position.z + distance * direction.z);
firstX = (int) (0.5f * (cursorPosition.x + boardWidth));
firstY = (int) (0.5f * (cursorPosition.z + boardHeight));
firstX = Math.max(firstX, 0);
firstX = Math.min(firstX, boardWidth - 1);
firstY = Math.max(firstY, 0);
firstY = Math.min(firstY, boardHeight - 1);
firstSet = true;
algorithm.calculate(firstX, firstY);
spawner = new Thread()
{
@Override
public void run()
{
// Wrap around
for (int y = 0; y < boardHeight; y++)
{
int x = algorithm.lines[y];
int wrappedX = (x + firstX - algorithm.firstOffsetX) % boardWidth;
int wrappedY = (y + firstY) % boardHeight;
if (y >= Math.min(boardWidth, boardHeight))
{
break;
}
spawnQueen(wrappedX, wrappedY, y, y == 0);
try
{
Thread.sleep(y == 0 ? 1000 : 200);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
};
spawner.start();
}
for (int i = 0; i < queens.length; i++)
{
if (queens[i] == null)
{
continue;
}
Queen q = queens[i];
if (q.position.y != BOARD_HEIGHT)
{
q.dy += dt * -9.81f;
if (q.position.y + q.dy < BOARD_HEIGHT)
{
q.position.y = BOARD_HEIGHT;
q.dy = 0.0f;
} else
{
q.position.y += q.dy;
}
}
}
}
@Override
public void render(float dt)
{
// Camera rotation
Matrix4 view = new Matrix4();
Texture.unbind();
queensFBO.bind();
Screen.clear();
view.rotate(Vector3.RIGHT, -lerpedCameraHeight);
view.rotate(Vector3.UP, -lerpedCameraRot);
view.translate(0, 0, -lerpedCameraDistance);
shader.set("view", view);
shader.set("tex", 0);
Queen.begin();
for (int i = 0; i < queens.length; i++)
{
if (queens[i] != null)
{
queens[i].render(shader);
}
}
FBO.unbind();
view.setIdentity();
view.rotate(Vector3.RIGHT, lerpedCameraHeight);
view.rotate(Vector3.UP, -lerpedCameraRot);
view.translate(0, 0, -lerpedCameraDistance);
shader.set("view", view);
Queen.begin();
for (int i = 0; i < queens.length; i++)
{
if (queens[i] != null)
{
queens[i].render(shader);
}
}
FBO.unbind();
boardTexture.bind(0);
shader.set("model", Matrix4.fromScale(boardWidth / 8, 1, boardWidth / 8));
boardFrame.getVAO().bind();
boardFrame.getVAO().enableAttribs();
boardFrame.getVAO().draw(DrawMode.TRIANGLES, boardFrame.getTriCount(), 0);
boardHeightmap.bind(1);
shader.set("heights", 1);
queensFBOTexture.bind(2);
shader.set("reflection", 2);
shader.set("model", Matrix4.fromScale(boardWidth / 2, 1, boardHeight / 2).set(3, 3, 1.0023f));
boardTop.getVAO().bind();
boardTop.getVAO().enableAttribs();
boardTop.getVAO().draw(DrawMode.TRIANGLES, boardTop.getTriCount(), 0);
}
private void spawnQueen(int x, int z, int index, boolean first)
{
Vector3 newPosition = new Vector3((x - boardWidth / 2.0f + 0.5f) * 2, 10.0f, (z - boardHeight / 2.0f + 0.5f) * 2);
Queen queen = new Queen(newPosition, first);
queens[index] = queen;
}
public static void main(String[] args)
{
RunConfiguration config = new RunConfiguration();
config.context.versionMajor = 3;
config.context.versionMinor = 3;
config.samples = 8;
config.screenWidth = WIDTH;
config.screenHeight = HEIGHT;
config.windowTitle = "The Eight Queens Puzzle";
config.fpsCap = 120;
Application.run(config, EightQueens.class);
}
}

View File

@ -0,0 +1,63 @@
package eightqueens;
import com.rr.core.Shader;
import com.rr.core.Texture;
import com.rr.core.VAO.DrawMode;
import com.rr.graphics.p3d.Model;
import com.rr.math.Matrix4;
import com.rr.math.Vector3;
import com.rr.res.Resource;
public class Queen
{
private static Model queenModel;
private static Texture queenTextureWhite;
private static Texture queenTextureBlack;
private static boolean white = false;
public static void init()
{
queenModel = Resource.internal.getModel("/eightqueens/queen.obj").createModel();
queenTextureWhite = Resource.internal.getTexture("/eightqueens/queenWhite.png");
queenTextureBlack = Resource.internal.getTexture("/eightqueens/queenBlack.png");
}
public final Vector3 position;
public float dy;
private final boolean first;
public Queen(Vector3 position, boolean first)
{
this.position = position;
this.dy = 0.0f;
this.first = first;
}
public void render(Shader shader)
{
if (first)
{
queenTextureBlack.bind(0);
white = false;
} else if (!white)
{
queenTextureWhite.bind(0);
white = true;
}
shader.set("model", Matrix4.fromTranslation(position.x, position.y, position.z));
queenModel.getVAO().draw(DrawMode.TRIANGLES, queenModel.getTriCount(), 0);
}
public static void begin()
{
queenModel.getVAO().bind();
queenModel.getVAO().enableAttribs();
}
public static void end()
{}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@ -0,0 +1,50 @@
#version 330 core
in vec2 pUv;
in vec3 pNormal;
in vec3 pToLight;
in vec3 pToCamera;
in vec3 pSize;
out vec4 color;
uniform sampler2D tex;
uniform sampler2D reflection;
uniform sampler2D heights;
void main(void)
{
vec2 uv = pUv;
if (pSize.z >= 1.002)
{
vec2 boardSize = pSize.xy / 4;
uv = mod(uv * boardSize, 1.0);
uv *= 0.96;
uv += 0.02;
}
vec3 normal = normalize(pNormal);
vec3 toLight = normalize(pToLight);
vec3 toCamera = normalize(pToCamera);
float lambert = max(dot(normalize(normal), normalize(toLight)), 0.2);
float specular = pow(max(dot(reflect(toLight, normal), toCamera), 0.0), 10.0) * 0.5;
color = texture(tex, uv) * lambert + vec4(1.0) * specular;
if (pSize.z >= 1.002)
{
float heightLeft = texture(heights, uv + vec2(-0.003, 0)).r;
float heightRight = texture(heights, uv + vec2(0.003, 0)).r;
float heightUp = texture(heights, uv + vec2(0, -0.003)).r;
float heightDown = texture(heights, uv + vec2(0, 0.003)).r;
vec3 nnormal = vec3(heightLeft - heightRight, 1.0, heightUp - heightDown);
float fresnel = 1.0 - max(dot(-toCamera, normal), 0.0);
vec4 reflectionColor = texture(reflection, gl_FragCoord.xy / vec2(1280.0, -720.0) + vec2(0, 1) + nnormal.xz * 0.1);
color = mix(color, reflectionColor, fresnel * 0.6 + 0.2);
}
}

View File

@ -0,0 +1,28 @@
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 uv;
out vec2 pUv;
out vec3 pNormal;
out vec3 pToLight;
out vec3 pToCamera;
out vec3 pSize;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main(void)
{
pUv = uv;
pNormal = (view * vec4(normal, 0.0)).xyz;
pToLight = vec3(10.0, 2.0, 2.0) - (view * model * vec4(position, 1.0)).xyz;
pToCamera = vec3(view[3][0], view[3][1], view[3][2]) - (model * vec4(position, 1.0)).xyz;
pSize = vec3(model[0][0], model[2][2], model[3][3]);
gl_Position = projection * view * model * vec4(position, 1.0);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

View File

@ -0,0 +1,45 @@
import sys, binascii
letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789"
def crc32(s):
return (~binascii.crc32(s,-1))&0xFFFFFFFF
def checksumPid(s):
crc = crc32(s)
crc = crc ^ (crc >> 16)
res = s
l = len(letters)
for i in (0,1):
b = crc & 0xff
pos = (b // l) ^ (b % l)
res += letters[pos%l]
crc >>= 8
return res
def pidFromSerial(s, l):
crc = crc32(s)
arr1 = [0]*l
for i in xrange(len(s)):
arr1[i%l] ^= ord(s[i])
crc_bytes = [crc >> 24 & 0xff, crc >> 16 & 0xff, crc >> 8 & 0xff, crc & 0xff]
for i in xrange(l):
arr1[i] ^= crc_bytes[i&3]
pid = ""
for i in xrange(l):
b = arr1[i] & 0xff
pid+=letters[(b >> 7) + ((b >> 5 & 3) ^ (b & 0x1f))]
return pid
print "Mobipocket PID calculator for Amazon Kindle. Copyright (c) 2007 Igor Skochinsky <skochinsky@mail.ru>"
if len(sys.argv)>1:
pid = pidFromSerial(sys.argv[1],7)+"*"
print "Mobipocked PID for Kindle serial# "+sys.argv[1]+" is "+checksumPid(pid)
else:
print "Usage: kindlepid.py <Kindle Serial Number>"

View File

@ -0,0 +1,150 @@
import sys,struct,binascii
class DrmException(Exception):
pass
#implementation of Pukall Cipher 1
def PC1(key, src, decryption=True):
sum1 = 0;
sum2 = 0;
keyXorVal = 0;
if len(key)!=16:
print "Bad key length!"
return None
wkey = []
for i in xrange(8):
wkey.append(ord(key[i*2])<<8 | ord(key[i*2+1]))
dst = ""
for i in xrange(len(src)):
temp1 = 0;
byteXorVal = 0;
for j in xrange(8):
temp1 ^= wkey[j]
sum2 = (sum2+j)*20021 + sum1
sum1 = (temp1*346)&0xFFFF
sum2 = (sum2+sum1)&0xFFFF
temp1 = (temp1*20021+1)&0xFFFF
byteXorVal ^= temp1 ^ sum2
curByte = ord(src[i])
if not decryption:
keyXorVal = curByte * 257;
curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF
if decryption:
keyXorVal = curByte * 257;
for j in xrange(8):
wkey[j] ^= keyXorVal;
dst+=chr(curByte)
return dst
def checksumPid(s):
letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789"
crc = (~binascii.crc32(s,-1))&0xFFFFFFFF
crc = crc ^ (crc >> 16)
res = s
l = len(letters)
for i in (0,1):
b = crc & 0xff
pos = (b // l) ^ (b % l)
res += letters[pos%l]
crc >>= 8
return res
class DrmStripper:
def loadSection(self, section):
if (section + 1 == self.num_sections):
endoff = len(self.data_file)
else:
endoff = self.sections[section + 1][0]
off = self.sections[section][0]
return self.data_file[off:endoff]
def patch(self, off, new):
self.data_file = self.data_file[:off] + new + self.data_file[off+len(new):]
def patchSection(self, section, new, in_off = 0):
if (section + 1 == self.num_sections):
endoff = len(self.data_file)
else:
endoff = self.sections[section + 1][0]
off = self.sections[section][0]
assert off + in_off + len(new) <= endoff
self.patch(off + in_off, new)
def parseDRM(self, data, count, pid):
pid = pid.ljust(16,'\0')
keyvec1 = "\x72\x38\x33\xB0\xB4\xF2\xE3\xCA\xDF\x09\x01\xD6\xE2\xE0\x3F\x96"
temp_key = PC1(keyvec1, pid, False)
temp_key_sum = sum(map(ord,temp_key)) & 0xff
found_key = None
for i in xrange(count):
verification, size, type, cksum, cookie = struct.unpack('>LLLBxxx32s', data[i*0x30:i*0x30+0x30])
cookie = PC1(temp_key, cookie)
ver,flags,finalkey,expiry,expiry2 = struct.unpack('>LL16sLL', cookie)
if verification == ver and cksum == temp_key_sum and (flags & 0x1F) == 1:
found_key = finalkey
break
return found_key
def __init__(self, data_file, pid):
if checksumPid(pid[0:-2]) != pid:
raise DrmException("invalid PID checksum")
pid = pid[0:-2]
self.data_file = data_file
header = data_file[0:72]
if header[0x3C:0x3C+8] != 'BOOKMOBI':
raise DrmException("invalid file format")
self.num_sections, = struct.unpack('>H', data_file[76:78])
self.sections = []
for i in xrange(self.num_sections):
offset, a1,a2,a3,a4 = struct.unpack('>LBBBB', data_file[78+i*8:78+i*8+8])
flags, val = a1, a2<<16|a3<<8|a4
self.sections.append( (offset, flags, val) )
sect = self.loadSection(0)
records, = struct.unpack('>H', sect[0x8:0x8+2])
crypto_type, = struct.unpack('>H', sect[0xC:0xC+2])
if crypto_type != 2:
raise DrmException("invalid encryption type: %d" % crypto_type)
# calculate the keys
drm_ptr, drm_count, drm_size, drm_flags = struct.unpack('>LLLL', sect[0xA8:0xA8+16])
found_key = self.parseDRM(sect[drm_ptr:drm_ptr+drm_size], drm_count, pid)
if not found_key:
raise DrmException("no key found. maybe the PID is incorrect")
# kill the drm keys
self.patchSection(0, "\0" * drm_size, drm_ptr)
# kill the drm pointers
self.patchSection(0, "\xff" * 4 + "\0" * 12, 0xA8)
# clear the crypto type
self.patchSection(0, "\0" * 2, 0xC)
# decrypt sections
print "Decrypting. Please wait...",
for i in xrange(1, records+1):
self.patchSection(i, PC1(found_key, self.loadSection(i)))
print "done"
def getResult(self):
return self.data_file
print "MobiDeDrm v0.01. Copyright (c) 2008 The Dark Reverser"
if len(sys.argv)<4:
print "Removes protection from Mobipocket books"
print "Usage: mobidedrm infile.mobi outfile.mobi PID"
else:
infile = sys.argv[1]
outfile = sys.argv[2]
pid = sys.argv[3]
data_file = file(infile, 'rb').read()
try:
file(outfile, 'wb').write(DrmStripper(data_file, pid).getResult())
except DrmException, e:
print "Error: %s" % e

View File

@ -0,0 +1,178 @@
# This is a python script. You need a Python interpreter to run it.
# For example, ActiveState Python, which exists for windows.
#
# Changelog
# 0.01 - Initial version
# 0.02 - Huffdic compressed books were not properly decrypted
import sys,struct,binascii
class DrmException(Exception):
pass
#implementation of Pukall Cipher 1
def PC1(key, src, decryption=True):
sum1 = 0;
sum2 = 0;
keyXorVal = 0;
if len(key)!=16:
print "Bad key length!"
return None
wkey = []
for i in xrange(8):
wkey.append(ord(key[i*2])<<8 | ord(key[i*2+1]))
dst = ""
for i in xrange(len(src)):
temp1 = 0;
byteXorVal = 0;
for j in xrange(8):
temp1 ^= wkey[j]
sum2 = (sum2+j)*20021 + sum1
sum1 = (temp1*346)&0xFFFF
sum2 = (sum2+sum1)&0xFFFF
temp1 = (temp1*20021+1)&0xFFFF
byteXorVal ^= temp1 ^ sum2
curByte = ord(src[i])
if not decryption:
keyXorVal = curByte * 257;
curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF
if decryption:
keyXorVal = curByte * 257;
for j in xrange(8):
wkey[j] ^= keyXorVal;
dst+=chr(curByte)
return dst
def checksumPid(s):
letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789"
crc = (~binascii.crc32(s,-1))&0xFFFFFFFF
crc = crc ^ (crc >> 16)
res = s
l = len(letters)
for i in (0,1):
b = crc & 0xff
pos = (b // l) ^ (b % l)
res += letters[pos%l]
crc >>= 8
return res
def getSizeOfTrailingDataEntries(ptr, size, flags):
def getSizeOfTrailingDataEntry(ptr, size):
bitpos, result = 0, 0
while True:
v = ord(ptr[size-1])
result |= (v & 0x7F) << bitpos
bitpos += 7
size -= 1
if (v & 0x80) != 0 or (bitpos >= 28) or (size == 0):
return result
num = 0
flags >>= 1
while flags:
if flags & 1:
num += getSizeOfTrailingDataEntry(ptr, size - num)
flags >>= 1
return num
class DrmStripper:
def loadSection(self, section):
if (section + 1 == self.num_sections):
endoff = len(self.data_file)
else:
endoff = self.sections[section + 1][0]
off = self.sections[section][0]
return self.data_file[off:endoff]
def patch(self, off, new):
self.data_file = self.data_file[:off] + new + self.data_file[off+len(new):]
def patchSection(self, section, new, in_off = 0):
if (section + 1 == self.num_sections):
endoff = len(self.data_file)
else:
endoff = self.sections[section + 1][0]
off = self.sections[section][0]
assert off + in_off + len(new) <= endoff
self.patch(off + in_off, new)
def parseDRM(self, data, count, pid):
pid = pid.ljust(16,'\0')
keyvec1 = "\x72\x38\x33\xB0\xB4\xF2\xE3\xCA\xDF\x09\x01\xD6\xE2\xE0\x3F\x96"
temp_key = PC1(keyvec1, pid, False)
temp_key_sum = sum(map(ord,temp_key)) & 0xff
found_key = None
for i in xrange(count):
verification, size, type, cksum, cookie = struct.unpack('>LLLBxxx32s', data[i*0x30:i*0x30+0x30])
cookie = PC1(temp_key, cookie)
ver,flags,finalkey,expiry,expiry2 = struct.unpack('>LL16sLL', cookie)
if verification == ver and cksum == temp_key_sum and (flags & 0x1F) == 1:
found_key = finalkey
break
return found_key
def __init__(self, data_file, pid):
if checksumPid(pid[0:-2]) != pid:
raise DrmException("invalid PID checksum")
pid = pid[0:-2]
self.data_file = data_file
header = data_file[0:72]
if header[0x3C:0x3C+8] != 'BOOKMOBI':
raise DrmException("invalid file format")
self.num_sections, = struct.unpack('>H', data_file[76:78])
self.sections = []
for i in xrange(self.num_sections):
offset, a1,a2,a3,a4 = struct.unpack('>LBBBB', data_file[78+i*8:78+i*8+8])
flags, val = a1, a2<<16|a3<<8|a4
self.sections.append( (offset, flags, val) )
sect = self.loadSection(0)
records, = struct.unpack('>H', sect[0x8:0x8+2])
extra_data_flags, = struct.unpack('>L', sect[0xF0:0xF4])
crypto_type, = struct.unpack('>H', sect[0xC:0xC+2])
if crypto_type != 2:
raise DrmException("invalid encryption type: %d" % crypto_type)
# calculate the keys
drm_ptr, drm_count, drm_size, drm_flags = struct.unpack('>LLLL', sect[0xA8:0xA8+16])
found_key = self.parseDRM(sect[drm_ptr:drm_ptr+drm_size], drm_count, pid)
if not found_key:
raise DrmException("no key found. maybe the PID is incorrect")
# kill the drm keys
self.patchSection(0, "\0" * drm_size, drm_ptr)
# kill the drm pointers
self.patchSection(0, "\xff" * 4 + "\0" * 12, 0xA8)
# clear the crypto type
self.patchSection(0, "\0" * 2, 0xC)
# decrypt sections
print "Decrypting. Please wait...",
for i in xrange(1, records+1):
data = self.loadSection(i)
extra_size = getSizeOfTrailingDataEntries(data, len(data), extra_data_flags)
self.patchSection(i, PC1(found_key, data[0:len(data) - extra_size]))
print "done"
def getResult(self):
return self.data_file
print "MobiDeDrm v0.02. Copyright (c) 2008 The Dark Reverser"
if len(sys.argv)<4:
print "Removes protection from Mobipocket books"
print "Usage:"
print " mobidedrm infile.mobi outfile.mobi PID"
else:
infile = sys.argv[1]
outfile = sys.argv[2]
pid = sys.argv[3]
data_file = file(infile, 'rb').read()
try:
file(outfile, 'wb').write(DrmStripper(data_file, pid).getResult())
except DrmException, e:
print "Error: %s" % e

View File

@ -0,0 +1,168 @@
# This is a python script. You need a Python interpreter to run it.
# For example, ActiveState Python, which exists for windows.
#
# Big Thanks to Igor SKOCHINSKY for providing me with all his information
# and source code relating to the inner workings of this compression scheme.
# Without it, I wouldn't be able to solve this as easily.
#
# Changelog
# 0.01 - Initial version
# 0.02 - Fix issue with size computing
# 0.03 - Fix issue with some files
import struct, sys
class BitReader:
def __init__(self, data):
self.data, self.pos, self.nbits = data + "\x00\x00\x00\x00", 0, len(data) * 8
def peek(self, n):
r, g = 0, 0
while g < n:
r, g = (r << 8) | ord(self.data[(self.pos+g)>>3]), g + 8 - ((self.pos+g) & 7)
return (r >> (g - n)) & ((1 << n) - 1)
def eat(self, n):
self.pos += n
return self.pos <= self.nbits
def left(self):
return self.nbits - self.pos
class HuffReader:
def __init__(self, huffs):
self.huffs = huffs
h = huffs[0]
if huffs[0][0:4] != 'HUFF' or huffs[0][4:8] != '\x00\x00\x00\x18':
raise ValueError('invalid huff1 header')
if huffs[1][0:4] != 'CDIC' or huffs[1][4:8] != '\x00\x00\x00\x10':
raise ValueError('invalid huff2 header')
self.entry_bits, = struct.unpack('>L', huffs[1][12:16])
off1,off2 = struct.unpack('>LL', huffs[0][16:24])
self.dict1 = struct.unpack('<256L', huffs[0][off1:off1+256*4])
self.dict2 = struct.unpack('<64L', huffs[0][off2:off2+64*4])
self.dicts = huffs[1:]
self.r = ''
def _unpack(self, bits, depth = 0):
if depth > 32:
raise ValueError('corrupt file')
while bits.left():
dw = bits.peek(32)
v = self.dict1[dw >> 24]
codelen = v & 0x1F
assert codelen != 0
code = dw >> (32 - codelen)
r = (v >> 8)
if not (v & 0x80):
while code < self.dict2[(codelen-1)*2]:
codelen += 1
code = dw >> (32 - codelen)
r = self.dict2[(codelen-1)*2+1]
r -= code
assert codelen != 0
if not bits.eat(codelen):
return
dicno = r >> self.entry_bits
off1 = 16 + (r - (dicno << self.entry_bits)) * 2
dic = self.dicts[dicno]
off2 = 16 + ord(dic[off1]) * 256 + ord(dic[off1+1])
blen = ord(dic[off2]) * 256 + ord(dic[off2+1])
slice = dic[off2+2:off2+2+(blen&0x7fff)]
if blen & 0x8000:
self.r += slice
else:
self._unpack(BitReader(slice), depth + 1)
def unpack(self, data):
self.r = ''
self._unpack(BitReader(data))
return self.r
class Sectionizer:
def __init__(self, filename, ident):
self.contents = file(filename, 'rb').read()
self.header = self.contents[0:72]
self.num_sections, = struct.unpack('>H', self.contents[76:78])
if self.header[0x3C:0x3C+8] != ident:
raise ValueError('Invalid file format')
self.sections = []
for i in xrange(self.num_sections):
offset, a1,a2,a3,a4 = struct.unpack('>LBBBB', self.contents[78+i*8:78+i*8+8])
flags, val = a1, a2<<16|a3<<8|a4
self.sections.append( (offset, flags, val) )
def loadSection(self, section):
if section + 1 == self.num_sections:
end_off = len(self.contents)
else:
end_off = self.sections[section + 1][0]
off = self.sections[section][0]
return self.contents[off:end_off]
def getSizeOfTrailingDataEntry(ptr, size):
bitpos, result = 0, 0
while True:
v = ord(ptr[size-1])
result |= (v & 0x7F) << bitpos
bitpos += 7
size -= 1
if (v & 0x80) != 0 or (bitpos >= 28) or (size == 0):
return result
def getSizeOfTrailingDataEntries(ptr, size, flags):
num = 0
flags >>= 1
while flags:
if flags & 1:
num += getSizeOfTrailingDataEntry(ptr, size - num)
flags >>= 1
return num
def unpackBook(input_file):
sect = Sectionizer(input_file, 'BOOKMOBI')
header = sect.loadSection(0)
crypto_type, = struct.unpack('>H', header[0xC:0xC+2])
if crypto_type != 0:
raise ValueError('The book is encrypted. Run mobidedrm first')
if header[0:2] != 'DH':
raise ValueError('invalid compression type')
extra_flags, = struct.unpack('>L', header[0xF0:0xF4])
records, = struct.unpack('>H', header[0x8:0x8+2])
huffoff,huffnum = struct.unpack('>LL', header[0x70:0x78])
huffs = [sect.loadSection(i) for i in xrange(huffoff, huffoff+huffnum)]
huff = HuffReader(huffs)
def decompressSection(nr):
data = sect.loadSection(nr)
trail_size = getSizeOfTrailingDataEntries(data, len(data), extra_flags)
return huff.unpack(data[0:len(data)-trail_size])
r = ''
for i in xrange(1, records+1):
r += decompressSection(i)
return r
print "MobiHuff v0.03"
print " Copyright (c) 2008 The Dark Reverser <dark.reverser@googlemail.com>"
if len(sys.argv)!=3:
print ""
print "Description:"
print " Unpacks the new mobipocket huffdic compression."
print " This program works with unencrypted files only."
print "Usage:"
print " mobihuff.py infile.mobi outfile.html"
else:
infile = sys.argv[1]
outfile = sys.argv[2]
try:
print "Decompressing...",
result = unpackBook(infile)
file(outfile, 'wb').write(result)
print "done"
except ValueError, e:
print
print "Error: %s" % e

View File

@ -0,0 +1,31 @@
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.control.Button;
public class main extends Application {
@Override
public void start(Stage stage) {
// declare button and pane
Pane pane = new Pane();
Button close_button = new Button("Close");
// add the button to the pane
pane.getChildren().add(close_button);
// generate the scene with the layout
Scene scene = new Scene(pane, 800, 600);
// set stage stuff
stage.setTitle("Basic Window");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
close_button.setOnAction(e -> {
stage.close();
});
}
public static void main(String[] args) { launch(args); }
}

View File

@ -0,0 +1,23 @@
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
@Override
public void start(final Stage stage) throws Exception {
Scene scene = new Scene(FXMLLoader.load(Main.class.getResource("window.fxml")));
scene.getStylesheets().add("stylesheet.css");
stage.setScene(scene);
//stage.setResizable(false); // keeps window from resizing
stage.setTitle("Image Viewer");
stage.setMinWidth(300);
stage.setMinHeight(300);
stage.show();
}
// needed because you know... it's java.
public static void main(String[] args) { launch(args); }
}

View File

@ -0,0 +1,5 @@
.root {
-fx-background: rgba(68, 68, 68, 0.8); // == #444444;
}
.button {
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<?scenebuilder-background-color 0x444444ff?>
<AnchorPane minHeight="300.0" minWidth="300.0" prefHeight="600.0" prefWidth="950.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" />

View File

@ -0,0 +1,34 @@
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.control.Button;
public class main extends Application {
@Override
public void start(Stage stage) {
stage.initStyle(StageStyle.TRANSPARENT);
Pane box = new Pane();
box.setStyle("-fx-background-color: rgba(68, 68, 69, 0.8)");
Button bttn = new Button("Close");
box.getChildren().add(bttn);
final Scene scene = new Scene(box,300, 250);
scene.setFill(null);
stage.setScene(scene);
stage.show();
bttn.setOnAction(e -> {
stage.close();
});
}
public static void main(String[] args) {
launch(args);
}
}

View File

@ -0,0 +1,161 @@
// Copyright 2003-2009 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
// www.source-code.biz, www.inventec.ch/chdh
//
// This module is multi-licensed and may be used under the terms
// of any of the following licenses:
//
// EPL, Eclipse Public License, http://www.eclipse.org/legal
// LGPL, GNU Lesser General Public License, http://www.gnu.org/licenses/lgpl.html
// AL, Apache License, http://www.apache.org/licenses
// BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php
//
// Please contact the author if you need another license.
// This module is provided "as is", without warranties of any kind.
/**
* A Base64 Encoder/Decoder.
*
* <p>
* This class is used to encode and decode data in Base64 format as described in RFC 1521.
*
* <p>
* Home page: <a href="http://www.source-code.biz">www.source-code.biz</a><br>
* Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br>
* Multi-licensed: EPL/LGPL/AL/BSD.
*
* <p>
* Version history:<br>
* 2003-07-22 Christian d'Heureuse (chdh): Module created.<br>
* 2005-08-11 chdh: Lincense changed from GPL to LGPL.<br>
* 2006-11-21 chdh:<br>
* &nbsp; Method encode(String) renamed to encodeString(String).<br>
* &nbsp; Method decode(String) renamed to decodeString(String).<br>
* &nbsp; New method encode(byte[],int) added.<br>
* &nbsp; New method decode(String) added.<br>
* 2009-07-16: Additional licenses (EPL/AL) added.<br>
* 2009-09-16: Additional license (BSD) added.<br>
* 2009-09-16: Additional license (BSD) added.<br>
* 2010-01-27: Package name added.<br>
*/
public class Base64Coder {
// Mapping table from 6-bit nibbles to Base64 characters.
private static char[] map1 = new char[64];
static {
int i=0;
for (char c='A'; c<='Z'; c++) map1[i++] = c;
for (char c='a'; c<='z'; c++) map1[i++] = c;
for (char c='0'; c<='9'; c++) map1[i++] = c;
map1[i++] = '+'; map1[i++] = '/'; }
// Mapping table from Base64 characters to 6-bit nibbles.
private static byte[] map2 = new byte[128];
static {
for (int i=0; i<map2.length; i++) map2[i] = -1;
for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
/**
* Encodes a string into Base64 format.
* No blanks or line breaks are inserted.
* @param s a String to be encoded.
* @return A String with the Base64 encoded data.
*/
public static String encodeString (String s) {
return new String(encode(s.getBytes())); }
/**
* Encodes a byte array into Base64 format.
* No blanks or line breaks are inserted.
* @param in an array containing the data bytes to be encoded.
* @return A character array with the Base64 encoded data.
*/
public static char[] encode (byte[] in) {
return encode(in,in.length); }
/**
* Encodes a byte array into Base64 format.
* No blanks or line breaks are inserted.
* @param in an array containing the data bytes to be encoded.
* @param iLen number of bytes to process in <code>in</code>.
* @return A character array with the Base64 encoded data.
*/
public static char[] encode (byte[] in, int iLen) {
int oDataLen = (iLen*4+2)/3; // output length without padding
int oLen = ((iLen+2)/3)*4; // output length including padding
char[] out = new char[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++] & 0xff;
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
int o0 = i0 >>> 2;
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
int o3 = i2 & 0x3F;
out[op++] = map1[o0];
out[op++] = map1[o1];
out[op] = op < oDataLen ? map1[o2] : '='; op++;
out[op] = op < oDataLen ? map1[o3] : '='; op++; }
return out; }
/**
* Decodes a string from Base64 format.
* @param s a Base64 String to be decoded.
* @return A String containing the decoded data.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static String decodeString (String s) {
return new String(decode(s)); }
/**
* Decodes a byte array from Base64 format.
* @param s a Base64 String to be decoded.
* @return An array containing the decoded data bytes.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static byte[] decode (String s) {
return decode(s.toCharArray()); }
/**
* Decodes a byte array from Base64 format.
* No blanks or line breaks are allowed within the Base64 encoded data.
* @param in a character array containing the Base64 encoded data.
* @return An array containing the decoded data bytes.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static byte[] decode (char[] in) {
int iLen = in.length;
if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
while (iLen > 0 && in[iLen-1] == '=') iLen--;
int oLen = (iLen*3) / 4;
byte[] out = new byte[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++];
int i1 = in[ip++];
int i2 = ip < iLen ? in[ip++] : 'A';
int i3 = ip < iLen ? in[ip++] : 'A';
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
int b0 = map2[i0];
int b1 = map2[i1];
int b2 = map2[i2];
int b3 = map2[i3];
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
int o0 = ( b0 <<2) | (b1>>>4);
int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
int o2 = ((b2 & 3)<<6) | b3;
out[op++] = (byte)o0;
if (op<oLen) out[op++] = (byte)o1;
if (op<oLen) out[op++] = (byte)o2; }
return out; }
// Dummy constructor.
private Base64Coder() {}
} // end class Base64Coder

View File

@ -0,0 +1,23 @@
import javafx.stage.Stage;
import javafx.stage.DirectoryChooser;
import java.io.File;
public class SelectDir {
private final Stage dirOpenerStage = new Stage();
private DirectoryChooser folderChooser = new DirectoryChooser();
private File selectedDir;
public File getSelectedDir() {
return selectedDir;
}
public void selecteDir() {
selectedDir = folderChooser.showDialog(dirOpenerStage);
if (selectedDir != null)
System.out.println("Chosen Directory: " + selectedDir);
else
System.out.println("No Directory Chosen" + selectedDir);
}
}

View File

@ -0,0 +1,28 @@
import javafx.stage.Stage;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import java.io.File;
public class SelectFile {
private final Stage fileOpenerStage = new Stage();
private FileChooser fileChooser = new FileChooser();
private File selectedFile;
public File getSelectedFile() {
return selectedFile;
}
public void selecteFile(String title, String[] filters) {
fileChooser.setTitle(title);
fileChooser.getExtensionFilters().addAll(
// new ExtensionFilter(filters),
new ExtensionFilter("All Files", "*.*"));
selectedFile = fileChooser.showOpenDialog(fileOpenerStage);
if (selectedFile != null)
System.out.println("Chosen File: " + selectedFile);
else
System.out.println("No File Chosen");
}
}

View File

@ -0,0 +1,14 @@
public class SingletonClass {
private static SingletonClass dbConnect = new SingletonClass();
// Instance passer
public static SingletonClass getInstance() { return dbConnect; }
// Init SingletonClass
private SingletonClass() {
}
}

BIN
src/Java/Jars/EpubViewer.jar Executable file

Binary file not shown.

BIN
src/Java/Jars/PdfViewer.jar Executable file

Binary file not shown.

1
src/Java/Jars/README Normal file
View File

@ -0,0 +1 @@
# Use these as reference and find them or updated versions...

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
/**
* Convert lines into the canonical MIME format, that is,
* terminate lines with CRLF. <p>
*
* This stream can be used with the Part.writeTo and Message.writeTo
* methods to generate the canonical MIME format of the data for the
* purpose of (e.g.) sending it via SMTP or computing a digital
* signature.
*/
public class CRLFOutputStream extends FilterOutputStream {
protected int lastb = -1;
protected static byte[] newline;
static {
newline = new byte[2];
newline[0] = (byte)'\r';
newline[1] = (byte)'\n';
}
public CRLFOutputStream(OutputStream os) {
super(os);
}
public void write(int b) throws IOException {
if (b == '\r') {
out.write(newline);
} else if (b == '\n') {
if (lastb != '\r')
out.write(newline);
} else {
out.write(b);
}
lastb = b;
}
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
int start = off;
len += off;
for (int i = start; i < len ; i++) {
if (b[i] == '\r') {
out.write(b, start, i - start);
out.write(newline);
start = i + 1;
} else if (b[i] == '\n') {
if (lastb != '\r') {
out.write(b, start, i - start);
out.write(newline);
}
start = i + 1;
}
lastb = b[i];
}
if ((len - start) > 0)
out.write(b, start, len - start);
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
/**
* Convert the various newline conventions to the local platform's
* newline convention. <p>
*
* This stream can be used with the Message.writeTo method to
* generate a message that uses the local plaform's line terminator
* for the purpose of (e.g.) saving the message to a local file.
*/
public class NewlineOutputStream extends FilterOutputStream {
private int lastb = -1;
private static byte[] newline;
public NewlineOutputStream(OutputStream os) {
super(os);
if (newline == null) {
String s = System.getProperty("line.separator");
if (s == null || s.length() <= 0)
s = "\n";
try {
newline = s.getBytes("iso-8859-1"); // really us-ascii
} catch (UnsupportedEncodingException ex) {
// should never happen
newline = new byte[] { (byte)'\n' };
}
}
}
public void write(int b) throws IOException {
if (b == '\r') {
out.write(newline);
} else if (b == '\n') {
if (lastb != '\r')
out.write(newline);
} else {
out.write(b);
}
lastb = b;
}
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
}

View File

@ -0,0 +1,384 @@
README for the demo programs in this directory
==============================================
These demo programs illustrate how to use the JavaMail API to
perform a number of common email functions. Note these these
programs are not intended to be examples of good user interfaces,
or good command line interfaces. No one is expected to actually
*use* these programs for anything real. Rather, their value is
in the source code. Don't look at their command line arguments
or user interface to figure out what JavaMail can do, look at
their source code. We strongly recommend that you read the
source code and understand what these programs are doing before
running them.
All of these programs are simple command line tools with a UNIX
style interface. On Windows you'll need to run them in an MS-DOS
window. We apologize in advance for the inconsistency in how these
programs accept options. There are generally two styles. The very
simple style (e.g., as used by copier.java) requires a fixed number
of arguments in a fixed order. Others (e.g., folderlist.java) take
UNIX-style options, many of which are optional, and which may appear
in any order. The following notes should help you figure it out,
but if in doubt, read the source code.
- copier.java
This program copies the specified messages from one folder to
another. Both folders must belong to the same store.
Usage:
java copier <urlname> <src> <dest> <start> <end>
Arguments (in order):
<urlname> : URL of the Store. The URL should include
the password as well (if needed).
Example: "imap://john:password@mailstore.com"
<src> : source folder
<dest> : destination folder
<start> : start message number
<end> : end message number
- folderlist.java
This program lists information about the folders in a Store.
Usage:
java folderlist -L <url> -T <protocol> -H <host> -U <user> -P <passwd>
[-R <root>] [-r] [-v] [-D] <pattern>
Options:
-L <url> : URL of the Store. The URL should include
the password as well (if needed).
Example: "imap://john:password@mailstore.com"
-T <protocol> : store protocol (Ex: "imap")
-H <host> : hostname of store.
-U <user> : username (if needed)
-P <passwd> : password (if needed)
-R <root> : root of the folder hierarchy. This is optional. If
not present, listing starts from the default folder.
-r : list recursively - folder and all subfolders.
-v : verbose - show more info about each folder.
-D : Turn on session debugging
<pattern> : folders that match this pattern are listed. Use "*"
as wildcard to match everything.
- monitor.java
Illustrates how to monitor a folder for interesting events,
like new mail arrival.
Usage:
java monitor <host> <user> <password> <mbox> <freq>
Arguments (in order):
<host> : hostname of store.
<user> : username (if needed)
<passwd> : password (if needed)
<mbox> : folder to monitor
<freq> : frequency of monitoring
- mover.java
Moves messages between folders. The folders must belong to the
same store.
Usage:
java mover -T <protocol> -H <host> -U <user> -P <passwd> [-v]
-s <src> -d <dest> [-x] <start> <end>
Options:
-T <protocol> : store protocol (Ex: "imap")
-H <host> : hostname of store.
-U <user> : username (if needed)
-P <passwd> : password (if needed)
-s <src> : source folder
-d <dest> : destination folder
-v : Optional verbose option
-x : Optional expunge option, to expunge the deleted
messages from src
Arguments (in order):
<start> : start message number
<end> : end message number
- msgmultisendsample.java
Demonstrates how to construct and send a multipart message.
Usage:
java msgmultisendsample <to> <from> <smtphost> true|false
Arguments (in order):
<to> : Recipient address
<from> : Sender address
<smtphost> : name of SMTP server
true|false : "true" to turn on session debugging, "false" otherwise
- msgsend.java
Send a simple text message. Optionally saves a copy
of the outgoing message in a folder (record-folder).
Most parameters to this program are optional. When
the program is run, it interactively asks for
the "To" and "Subject" fields if not already available.
Then the program expects the body of the message.
After you type in the body, hit Ctrl-D on Unix
systems or Ctrl-Z on Windows systems to send
the message.
Usage:
java msgsend -L <store-url> -T <protocol> -H <host> -U <user>
-P <passwd> -s <subject> -o <from> -c <cc> -b <bcc>
-f <record> -M <smtphost> [-d] <to>
Options:
-L <store-url> : URL of the store for the record-folder
-T <protocol> : If <store-url> is not present, this indicates
the store protocol for the record-folder.
-H <host> : If <store-url> is not present, this indicates
the hostname for the record-folder.
-U <user> : If <store-url> is not present, this indicates
the username for the record-folder.
-P <passwd> : If <store-url> is not present, this indicates
the password for the record-folder.
-f <record> : name of record-folder.
-M <smtphost> : Host name of SMTP server. Defaults to "localhost"
which often works on UNIX but rarely on Windows.
-s <subject> : Subject of message to be sent
-o <from> : From address of message to be sent
-c <cc> : Cc address of message to be sent
-b <bcc> : Bcc address of message to be sent
-d : Turn on session debugging.
-a <file> : Include file as an attachment with the message
Argument:
<to> : To address of message to be sent
- msgsendsample.java
Demonstrates how to construct and send a simple text message.
Usage:
java msgsendsample <to> <from> <smtphost> true|false
Arguments (in order):
<to> : Recipient address
<from> : Sender address
<smtphost> : name of SMTP server
true|false : "true" to turn on session debugging, "false" otherwise
- msgshow.java
Displays message(s) from a folder or from stdin.
Usage:
java msgshow -L <url> -T <protocol> -H <host> -p <port>
-U <user> -P <password> -f <mailbox>
[-D] [-s] [-S] [-a] [-v] [msgnum]
java msgshow -m [-D] [-s] [-S] [-v]
Options:
-L <url> : URL of the Store. The URL should include
the password as well (if needed).
Example: "imap://john:password@mailstore.com"
-T <protocol> : If <url> is not present, this indicates
the store protocol
-H <host> : If <url> is not present, this indicates
the hostname
-p <port> : If <url> is not present, this indicates
the port number (usually not needed)
-U <user> : If <url> is not present, this indicates
the username
-P <passwd> : If <url> is not present, this indicates
the password
-f <mailbox> : Folder to open
-m : Read message from standard input
-D : Turn on session debugging
-s : Show the structure of the message, but not the contents
-S : Save attachments to appropriately named files
-a : Show ALERTS and NOTIFICATIONS from the Store
-v : Verbose mode - show total messages and number of new messages
Argument:
<msgnum> : the message to be displayed. If this
parameter is not present, all messages in the
folder are displayed.
- namespace.java
Displays the namespaces supported by a store.
Usage:
java namespace -L <url> -T <protocol> -H <host> -p <port>
-U <user> -P <password> [-D]
Options:
-L <url> : URL of the Store. The URL should include
the password as well (if needed).
Example: "imap://john:password@mailstore.com"
-T <protocol> : If <url> is not present, this indicates
the store protocol
-H <host> : If <url> is not present, this indicates
the hostname
-p <port> : If <url> is not present, this indicates
the port number (usually not needed)
-U <user> : If <url> is not present, this indicates
the username
-P <passwd> : If <url> is not present, this indicates
the password
-D : Turn on session debugging
- populate.java
Copies an entire folder hierarchy from one message store to
another.
Usage:
java populate -s <src-url> -d <dest-url> -D -f
Options:
-s <src-url> : URL of source folder
-d <dest-url> : URL of destination folder
-D : Turn on session debugging
-f : force the copy to occur even if the destination
folder already exists
-S : skip special folders named "SCCS", "Drafts", "Trash", and
"Shared Folders"
-c : clear out old folders before copying messages
-P : don't preserve flags when copying messages
- registry.java
Demonstrates how to query the JavaMail "registry" for providers,
set default providers, etc.
Usage:
java registry
- search.java
Search the given folder for messages matching the
given criteria. Illustrates the use of the
javax.mail.search package.
Usage:
java search -L <url> -T <prot> -H <host> -U <user> -P <passwd>
-f <folder> -subject <subject> -from <from>
-today -or
Options:
-L <url> : URL of the store
-T <protocol> : If <url> is not present, this indicates
the store protocol
-H <host> : If <url> is not present, this indicates
the hostname
-U <user> : If <url> is not present, this indicates
the username
-P <passwd> : If <url> is not present, this indicates
the password
-f <folder> : folder to search
-or : If this flag is present, the search will
return messages that match any one of the
below criteria. Else the search will only
return messages that match all the criteria
-subject <subject> : search for messages containing this string
as the Subject
-from <from> : search for messages containing this string
as the From address
-today : search for messages received today
- sendfile.java
Send the specified file to the given address. The file
is sent as an attachment. An SMTP server must be available.
Usage:
java sendfile <to> <from> <smtphost> <file> true|false
Arguments (in order):
<to> : Recipient address
<from> : Sender address
<smtphost> : name of SMTP server
<file> : name of file to be sent
true|false : "true" to turn on session debugging, "false" otherwise
- sendhtml.java
The sendhtml program works like the msgsend program, taking
the same options and input, but the text collected from the
user is sent as type "text/html" instead of "text/plain".
This program is a good example of how to send arbitrary
string data as any arbitrary MIME type.
- smtpsend.java
Takes the same options as the msgsend program, but illustrates
how to handle SMTP-specific error codes. Also accepts the
following options:
Option:
-v : verbose output
-A : use SMTP authentication
-S : use SSL
- transport.java
Illustrates how to use an explicit Transport object, how to
handle transport exceptions, and how to handle transport events.
Usage:
java transport <to> <from> <smtphost> <file> true|false
Arguments (in order):
<to> : Recipient address
<from> : Sender address
<smtphost> : name of SMTP server
<file> : name of file to be sent
true|false : "true" to turn on session debugging, "false" otherwise
- uidmsgshow.java
The uidmsgshow program works like the msgshow program, taking
the same options, except instead of using message numbers, it
uses message UID's. This will typically only work with IMAP
message stores.

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
/**
* this Frame provides a utility class for displaying a single
* Component in a Frame.
*
* @author Christopher Cotton
*/
public class ComponentFrame extends JFrame {
/**
* creates the frame
* @param what the component to display
*/
public ComponentFrame(Component what) {
this(what, "Component Frame");
}
/**
* creates the frame with the given name
* @param what the component to display
* @param name the name of the Frame
*/
public ComponentFrame(Component what, String name) {
super(name);
// make sure that we close and dispose ourselves when needed
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
// default size of the frame
setSize(700,600);
// we want to display just the component in the entire frame
if (what != null) {
getContentPane().add("Center", what);
}
}
}

View File

@ -0,0 +1,160 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.mail.*;
import java.util.Date;
import javax.swing.table.AbstractTableModel;
/**
* Maps the messages in a Folder to the Swing's Table Model
*
* @author Christopher Cotton
* @author Bill Shannon
*/
public class FolderModel extends AbstractTableModel {
Folder folder;
Message[] messages;
String[] columnNames = { "Date", "From", "Subject"};
Class[] columnTypes = { String.class, String.class, String.class };
public void setFolder(Folder what) throws MessagingException {
if (what != null) {
// opened if needed
if (!what.isOpen()) {
what.open(Folder.READ_WRITE);
}
// get the messages
messages = what.getMessages();
cached = new String[messages.length][];
} else {
messages = null;
cached = null;
}
// close previous folder and switch to new folder
if (folder != null)
folder.close(true);
folder = what;
fireTableDataChanged();
}
public Message getMessage(int which) {
return messages[which];
}
//---------------------
// Implementation of the TableModel methods
//---------------------
public String getColumnName(int column) {
return columnNames[column];
}
public Class getColumnClass(int column) {
return columnTypes[column];
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
if (messages == null)
return 0;
return messages.length;
}
public Object getValueAt(int aRow, int aColumn) {
switch(aColumn) {
case 0: // date
case 1: // From String[] what = getCachedData(aRow);
case 2: // Subject
String[] what = getCachedData(aRow);
if (what != null) {
return what[aColumn];
} else {
return "";
}
default:
return "";
}
}
protected static String[][] cached;
protected String[] getCachedData(int row) {
if (cached[row] == null) {
try{
Message m = messages[row];
String[] theData = new String[4];
// Date
Date date = m.getSentDate();
if (date == null) {
theData[0] = "Unknown";
} else {
theData[0] = date.toString();
}
// From
Address[] adds = m.getFrom();
if (adds != null && adds.length != 0) {
theData[1] = adds[0].toString();
} else {
theData[1] = "";
}
// Subject
String subject = m.getSubject();
if (subject != null) {
theData[2] = subject;
} else {
theData[2] = "(No Subject)";
}
cached[row] = theData;
}
catch (MessagingException e) {
e.printStackTrace();
}
}
return cached[row];
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.swing.tree.DefaultMutableTreeNode;
import javax.mail.Store;
import javax.mail.Folder;
import javax.mail.MessagingException;
/**
* Node which represents a Folder in the javax.mail apis.
*
* @author Christopher Cotton
*/
public class FolderTreeNode extends DefaultMutableTreeNode {
protected Folder folder = null;
protected boolean hasLoaded = false;
/**
* creates a tree node that points to the particular Store.
*
* @param what the store for this node
*/
public FolderTreeNode(Folder what) {
super(what);
folder = what;
}
/**
* a Folder is a leaf if it cannot contain sub folders
*/
public boolean isLeaf() {
try {
if ((folder.getType() & Folder.HOLDS_FOLDERS) == 0)
return true;
} catch (MessagingException me) { }
// otherwise it does hold folders, and therefore not
// a leaf
return false;
}
/**
* returns the folder for this node
*/
public Folder getFolder() {
return folder;
}
/**
* return the number of children for this folder node. The first
* time this method is called we load up all of the folders
* under the store's defaultFolder
*/
public int getChildCount() {
if (!hasLoaded) {
loadChildren();
}
return super.getChildCount();
}
protected void loadChildren() {
// if it is a leaf, just say we have loaded them
if (isLeaf()) {
hasLoaded = true;
return;
}
try {
// Folder[] sub = folder.listSubscribed();
Folder[] sub = folder.list();
// add a FolderTreeNode for each Folder
int num = sub.length;
for(int i = 0; i < num; i++) {
FolderTreeNode node = new FolderTreeNode(sub[i]);
// we used insert here, since add() would make
// another recursive call to getChildCount();
insert(node, i);
}
} catch (MessagingException me) {
me.printStackTrace();
}
}
/**
* override toString() since we only want to display a folder's
* name, and not the full path of the folder
*/
public String toString() {
return folder.getName();
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.*;
import javax.mail.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
/**
* @author Christopher Cotton
* @author Bill Shannon
*/
public class FolderViewer extends JPanel {
FolderModel model = new FolderModel();
JScrollPane scrollpane;
JTable table;
public FolderViewer() {
this(null);
}
public FolderViewer(Folder what) {
super(new GridLayout(1,1));
table = new JTable(model);
table.setShowGrid(false);
scrollpane = new JScrollPane(table);
// setup the folder we were given
setFolder(what);
// find out what is pressed
table.getSelectionModel().addListSelectionListener(
new FolderPressed());
scrollpane.setPreferredSize(new Dimension(700, 300));
add(scrollpane);
}
/**
* Change the current Folder for the Viewer
*
* @param what the folder to be viewed
*/
public void setFolder(Folder what) {
try {
table.getSelectionModel().clearSelection();
if (SimpleClient.mv != null)
SimpleClient.mv.setMessage(null);
model.setFolder(what);
scrollpane.invalidate();
scrollpane.validate();
} catch (MessagingException me) {
me.printStackTrace();
}
}
class FolderPressed implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
if (model != null && !e.getValueIsAdjusting()) {
ListSelectionModel lm = (ListSelectionModel) e.getSource();
int which = lm.getMaxSelectionIndex();
if (which != -1) {
// get the message and display it
Message msg = model.getMessage(which);
SimpleClient.mv.setMessage(msg);
}
}
}
}
}

View File

@ -0,0 +1,255 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.*;
import java.awt.event.*;
import javax.mail.*;
import javax.activation.*;
import java.util.Date;
import java.io.IOException;
import javax.swing.JPanel;
/**
* @author Christopher Cotton
* @author Bill Shannon
*/
public class MessageViewer extends JPanel implements CommandObject {
Message displayed = null;
DataHandler dataHandler = null;
String verb = null;
Component mainbody;
TextArea headers;
public MessageViewer() {
this(null);
}
public MessageViewer(Message what) {
// set our layout
super(new GridBagLayout());
// add the toolbar
addToolbar();
GridBagConstraints gb = new GridBagConstraints();
gb.gridwidth = GridBagConstraints.REMAINDER;
gb.fill = GridBagConstraints.BOTH;
gb.weightx = 1.0;
gb.weighty = 0.0;
// add the headers
headers = new TextArea("", 4, 80, TextArea.SCROLLBARS_NONE);
headers.setEditable(false);
add(headers, gb);
// now display our message
setMessage(what);
}
/**
* sets the current message to be displayed in the viewer
*/
public void setMessage(Message what) {
displayed = what;
if (mainbody != null)
remove(mainbody);
if (what != null) {
loadHeaders();
mainbody = getBodyComponent();
} else {
headers.setText("");
TextArea dummy = new TextArea("", 24, 80, TextArea.SCROLLBARS_NONE);
dummy.setEditable(false);
mainbody = dummy;
}
// add the main body
GridBagConstraints gb = new GridBagConstraints();
gb.gridwidth = GridBagConstraints.REMAINDER;
gb.fill = GridBagConstraints.BOTH;
gb.weightx = 1.0;
gb.weighty = 1.0;
add(mainbody, gb);
invalidate();
validate();
}
protected void addToolbar() {
GridBagConstraints gb = new GridBagConstraints();
gb.gridheight = 1;
gb.gridwidth = 1;
gb.fill = GridBagConstraints.NONE;
gb.anchor = GridBagConstraints.WEST;
gb.weightx = 0.0;
gb.weighty = 0.0;
gb.insets = new Insets(4,4,4,4);
// structure button
gb.gridwidth = GridBagConstraints.REMAINDER; // only for the last one
Button b = new Button("Structure");
b.addActionListener( new StructureAction());
add(b, gb);
}
protected void loadHeaders() {
// setup what we want in our viewer
StringBuffer sb = new StringBuffer();
// date
sb.append("Date: ");
try {
Date duh = displayed.getSentDate();
if (duh != null) {
sb.append(duh.toString());
} else {
sb.append("Unknown");
}
sb.append("\n");
// from
sb.append("From: ");
Address[] adds = displayed.getFrom();
if (adds != null && adds.length > 0) {
sb.append(adds[0].toString());
}
sb.append("\n");
// to
sb.append("To: ");
adds = displayed.getRecipients(Message.RecipientType.TO);
if (adds != null && adds.length > 0) {
sb.append(adds[0].toString());
}
sb.append("\n");
// subject
sb.append("Subject: ");
sb.append(displayed.getSubject());
headers.setText(sb.toString());
} catch (MessagingException me) {
headers.setText("");
}
}
protected Component getBodyComponent() {
//------------
// now get a content viewer for the main type...
//------------
try {
DataHandler dh = displayed.getDataHandler();
CommandInfo ci = dh.getCommand("view");
if (ci == null) {
throw new MessagingException("view command failed on: " +
displayed.getContentType());
}
Object bean = dh.getBean(ci);
if (bean instanceof Component) {
return (Component)bean;
} else {
throw new MessagingException("bean is not a component " +
bean.getClass().toString());
}
} catch (MessagingException me) {
return new Label(me.toString());
}
}
/**
* the CommandObject method to accept our DataHandler
* @param dh the datahandler used to get the content
*/
public void setCommandContext(String verb,
DataHandler dh) throws IOException {
this.verb = verb;
dataHandler = dh;
Object o = dh.getContent();
if (o instanceof Message) {
setMessage((Message)o);
}
else {
System.out.println(
"MessageViewer - content not a Message object, " + o);
if (o != null){
System.out.println(o.getClass().toString());
}
}
}
class StructureAction implements ActionListener {
StringBuffer sb;
public void actionPerformed(ActionEvent e) {
System.out.println("\n\nMessage Structure");
dumpPart("", displayed);
}
protected void dumpPart(String prefix, Part p) {
try {
System.out.println(prefix + "----------------");
System.out.println(prefix +
"Content-Type: " + p.getContentType());
System.out.println(prefix +
"Class: " + p.getClass().toString());
Object o = p.getContent();
if (o == null) {
System.out.println(prefix + "Content: is null");
} else {
System.out.println(prefix +
"Content: " + o.getClass().toString());
}
if (o instanceof Multipart) {
String newpref = prefix + "\t";
Multipart mp = (Multipart)o;
int count = mp.getCount();
for (int i = 0; i < count; i++) {
dumpPart(newpref, mp.getBodyPart(i));
}
}
} catch (MessagingException e) {
e.printStackTrace();
} catch (IOException ioex) {
System.out.println("Cannot get content" + ioex.getMessage());
}
}
}
}

View File

@ -0,0 +1,186 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.beans.*;
import javax.activation.*;
import javax.mail.*;
import javax.swing.JPanel;
/**
* A Viewer Bean for the type multipart/mixed
*
* @author Christopher Cotton
*/
public class MultipartViewer extends JPanel implements CommandObject {
protected DataHandler dh = null;
protected String verb = null;
public MultipartViewer() {
super(new GridBagLayout());
}
public void setCommandContext(String verb, DataHandler dh) throws IOException {
this.verb = verb;
this.dh = dh;
// get the content, and hope it is a Multipart Object
Object content = dh.getContent();
if (content instanceof Multipart) {
setupDisplay((Multipart)content);
} else {
setupErrorDisplay(content);
}
}
protected void setupDisplay(Multipart mp) {
// we display the first body part in a main frame on the left, and then
// on the right we display the rest of the parts as attachments
GridBagConstraints gc = new GridBagConstraints();
gc.gridheight = GridBagConstraints.REMAINDER;
gc.fill = GridBagConstraints.BOTH;
gc.weightx = 1.0;
gc.weighty = 1.0;
// get the first part
try {
BodyPart bp = mp.getBodyPart(0);
Component comp = getComponent(bp);
add(comp, gc);
} catch (MessagingException me) {
add(new Label(me.toString()), gc);
}
// see if there are more than one parts
try {
int count = mp.getCount();
// setup how to display them
gc.gridwidth = GridBagConstraints.REMAINDER;
gc.gridheight = 1;
gc.fill = GridBagConstraints.NONE;
gc.anchor = GridBagConstraints.NORTH;
gc.weightx = 0.0;
gc.weighty = 0.0;
gc.insets = new Insets(4,4,4,4);
// for each one we create a button with the content type
for(int i = 1; i < count; i++) { // we skip the first one
BodyPart curr = mp.getBodyPart(i);
String label = null;
if (label == null) label = curr.getFileName();
if (label == null) label = curr.getDescription();
if (label == null) label = curr.getContentType();
Button but = new Button(label);
but.addActionListener( new AttachmentViewer(curr));
add(but, gc);
}
} catch(MessagingException me2) {
me2.printStackTrace();
}
}
protected Component getComponent(BodyPart bp) {
try {
DataHandler dh = bp.getDataHandler();
CommandInfo ci = dh.getCommand("view");
if (ci == null) {
throw new MessagingException(
"view command failed on: " +
bp.getContentType());
}
Object bean = dh.getBean(ci);
if (bean instanceof Component) {
return (Component)bean;
} else {
if (bean == null)
throw new MessagingException(
"bean is null, class " + ci.getCommandClass() +
" , command " + ci.getCommandName());
else
throw new MessagingException(
"bean is not a awt.Component" +
bean.getClass().toString());
}
}
catch (MessagingException me) {
return new Label(me.toString());
}
}
protected void setupErrorDisplay(Object content) {
String error;
if (content == null)
error = "Content is null";
else
error = "Object not of type Multipart, content class = " +
content.getClass().toString();
System.out.println(error);
Label lab = new Label(error);
add(lab);
}
class AttachmentViewer implements ActionListener {
BodyPart bp = null;
public AttachmentViewer(BodyPart part) {
bp = part;
}
public void actionPerformed(ActionEvent e) {
ComponentFrame f = new ComponentFrame(
getComponent(bp), "Attachment");
f.pack();
f.show();
}
}
}

View File

@ -0,0 +1,124 @@
SimpleClient
------------
Notes:
======
This should not be taken as a demo of how to use the Swing API, but
rather a very simple graphical mail client. It shows how viewers can
be used to display the content from mail messages. It also (like the
other demos) shows how to retrieve Folders from a Store, Messages
from a Folder, and content from Messages.
To run the demo:
================
1. If you're using JDK 1.1.x, download the latest version of the JFC
(Swing) APIs from http://java.sun.com/products/jfc/download.html.
The SimpleClient uses at least version 1.1 of Swing.
If you're using JDK 1.2 (J2SE 1.2) or newer, Swing is included
and no separate download is necessary.
We *strongly* encourage you to use the latest version of J2SE,
which you can download from http://java.sun.com/j2se/.
2. Set your CLASSPATH to include the "mail.jar", "activation.jar",
and (if you're using JDK 1.1.x and downloaded Swing separately)
"swingall.jar", and the current directory. For example:
For JDK 1.1 on UNIX:
export CLASSPATH=/u/me/download/mail.jar:/u/me/download/activation.jar:/u/me/download/swingall.jar:.
For JDK 1.2 and newer on UNIX:
export CLASSPATH=/u/me/download/mail.jar:/u/me/download/activation.jar:.
3. Go to the demo/client directory
4. Compile all the files using your Java compiler. For example:
javac *.java
5. Run the demo. For example:
java SimpleClient -L imap://username:password@hostname/
Note that SimpleClient expects to read the "simple.mailcap"
file from the current directory. The simple.mailcap file
contains configuration information about viewers needed by
the SimpleClient demo program.
Overview of the Classes
=======================
Main Classes:
SimpleClient = contains main().
Uses the parameters to the application to
locate the correct Store. e.g.
SimpleClient -L imap://cotton:secret@snow-goon/
It will create the main frame and
creates a tree. The tree uses the
StoreTreeNodes and FolderTreeNodes.
StoreTreeNode = subclass of Swing's DefaultMutableTreeNode.
This class shows how to get Folders from
the Store.
FolderTreeNode = subclass of Swing's DefaultMutableTreeNode.
If the folder has messages, it will create
a FolderViewer. Otherwise it will add the
subfolders to the tree.
SimpleAuthenticator = subclass of javax.mail.Authenticator. If
the Store is missing the username or the
password, this authenticator will be used.
It displays a dialog requesting the
information from the user.
Viewing Folders:
FolderViewer = Uses a Swing Table to display all of the
Message in a Folder. The "model" of the
data for this Table is a FolderModel which
knows how to get displayable information
from a Message.
JAF Viewers:
MessageViewer = Uses the content of the DataHandler. The
content will be a javax.mail.Message
object. Displays the headers and then
uses the JAF to find another viewer for
the content type of the Message. (either
multipart/mixed, image/gif, or text/plain)
MultipartViewer = Uses the content of the DataHandler. The
content will be a javax.mail.Multipart
object. Uses the JAF to find another
viewer for the first BodyPart's content.
Also puts Buttons (as "attachments") for
the rest of the BodyParts. When the
Button are pressed, it uses the JAF to
find a viewer for the BodyPart's content,
and displays it in a separate frame (using
ComponentFrame).
TextViewer = Uses the content of the DataHandler. The
content will be either a java.lang.String
object, or a java.io.InputStream object.
Creates a TextArea and sets the text using
the String or InputStream.
Support Classes:
ComponentFrame = support class which takes a java.awt.Component
and displays it in a Frame.

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.mail.*;
import java.net.InetAddress;
import java.awt.*;
import javax.swing.*;
/**
* Simple Authenticator for requesting password information.
*
* @author Christopher Cotton
* @author Bill Shannon
*/
public class SimpleAuthenticator extends Authenticator {
Frame frame;
String username;
String password;
public SimpleAuthenticator(Frame f) {
this.frame = f;
}
protected PasswordAuthentication getPasswordAuthentication() {
// given a prompt?
String prompt = getRequestingPrompt();
if (prompt == null)
prompt = "Please login...";
// protocol
String protocol = getRequestingProtocol();
if (protocol == null)
protocol = "Unknown protocol";
// get the host
String host = null;
InetAddress inet = getRequestingSite();
if (inet != null)
host = inet.getHostName();
if (host == null)
host = "Unknown host";
// port
String port = "";
int portnum = getRequestingPort();
if (portnum != -1)
port = ", port " + portnum + " ";
// Build the info string
String info = "Connecting to " + protocol + " mail service on host " +
host + port;
//JPanel d = new JPanel();
// XXX - for some reason using a JPanel here causes JOptionPane
// to display incorrectly, so we workaround the problem using
// an anonymous JComponent.
JComponent d = new JComponent() { };
GridBagLayout gb = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
d.setLayout(gb);
c.insets = new Insets(2, 2, 2, 2);
c.anchor = GridBagConstraints.WEST;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 0.0;
d.add(constrain(new JLabel(info), gb, c));
d.add(constrain(new JLabel(prompt), gb, c));
c.gridwidth = 1;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.NONE;
c.weightx = 0.0;
d.add(constrain(new JLabel("Username:"), gb, c));
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1.0;
String user = getDefaultUserName();
JTextField username = new JTextField(user, 20);
d.add(constrain(username, gb, c));
c.gridwidth = 1;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.EAST;
c.weightx = 0.0;
d.add(constrain(new JLabel("Password:"), gb, c));
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 1.0;
JPasswordField password = new JPasswordField("", 20);
d.add(constrain(password, gb, c));
// XXX - following doesn't work
if (user != null && user.length() > 0)
password.requestFocus();
else
username.requestFocus();
int result = JOptionPane.showConfirmDialog(frame, d, "Login",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.OK_OPTION)
return new PasswordAuthentication(username.getText(),
password.getText());
else
return null;
}
private Component constrain(Component cmp,
GridBagLayout gb, GridBagConstraints c) {
gb.setConstraints(cmp, c);
return (cmp);
}
}

View File

@ -0,0 +1,169 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.tree.*;
import javax.swing.event.*;
/**
* Demo app that shows a very simple Mail Client
*
* @author Christopher Cotton
* @author Bill Shannon
*/
public class SimpleClient {
static Vector url = new Vector();
static FolderViewer fv;
static MessageViewer mv;
public static void main(String argv[]) {
boolean usage = false;
for (int optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-L")) {
url.addElement(argv[++optind]);
} else if (argv[optind].startsWith("-")) {
usage = true;
break;
} else {
usage = true;
break;
}
}
if (usage || url.size() == 0) {
System.out.println("Usage: SimpleClient -L url");
System.out.println(" where url is protocol://username:password@hostname/");
System.exit(1);
}
try {
// Set up our Mailcap entries. This will allow the JAF
// to locate our viewers.
File capfile = new File("simple.mailcap");
if (!capfile.isFile()) {
System.out.println(
"Cannot locate the \"simple.mailcap\" file.");
System.exit(1);
}
CommandMap.setDefaultCommandMap( new MailcapCommandMap(
new FileInputStream(capfile)));
JFrame frame = new JFrame("Simple JavaMail Client");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}});
//frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Get a Store object
SimpleAuthenticator auth = new SimpleAuthenticator(frame);
Session session =
Session.getDefaultInstance(System.getProperties(), auth);
//session.setDebug(true);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
// create a node for each store we have
for (Enumeration e = url.elements() ; e.hasMoreElements() ;) {
String urlstring = (String) e.nextElement();
URLName urln = new URLName(urlstring);
Store store = session.getStore(urln);
StoreTreeNode storenode = new StoreTreeNode(store);
root.add(storenode);
}
DefaultTreeModel treeModel = new DefaultTreeModel(root);
JTree tree = new JTree(treeModel);
tree.addTreeSelectionListener(new TreePress());
/* Put the Tree in a scroller. */
JScrollPane sp = new JScrollPane();
sp.setPreferredSize(new Dimension(250, 300));
sp.getViewport().add(tree);
/* Create a double buffered JPanel */
JPanel sv = new JPanel(new BorderLayout());
sv.add("Center", sp);
fv = new FolderViewer(null);
JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
sv, fv);
jsp.setOneTouchExpandable(true);
mv = new MessageViewer();
JSplitPane jsp2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
jsp, mv);
jsp2.setOneTouchExpandable(true);
frame.getContentPane().add(jsp2);
frame.pack();
frame.show();
} catch (Exception ex) {
System.out.println("SimpletClient caught exception");
ex.printStackTrace();
System.exit(1);
}
}
}
class TreePress implements TreeSelectionListener {
public void valueChanged(TreeSelectionEvent e) {
TreePath path = e.getNewLeadSelectionPath();
if (path != null) {
Object o = path.getLastPathComponent();
if (o instanceof FolderTreeNode) {
FolderTreeNode node = (FolderTreeNode)o;
Folder folder = node.getFolder();
try {
if ((folder.getType() & Folder.HOLDS_MESSAGES) != 0) {
SimpleClient.fv.setFolder(folder);
}
} catch (MessagingException me) { }
}
}
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.swing.tree.DefaultMutableTreeNode;
import javax.mail.*;
/**
* Node which represents a Store in the javax.mail apis.
*
* @author Christopher Cotton
*/
public class StoreTreeNode extends DefaultMutableTreeNode {
protected Store store = null;
protected Folder folder = null;
protected String display = null;
/**
* creates a tree node that points to the particular Store.
*
* @param what the store for this node
*/
public StoreTreeNode(Store what) {
super(what);
store = what;
}
/**
* a Store is never a leaf node. It can always contain stuff
*/
public boolean isLeaf() {
return false;
}
/**
* return the number of children for this store node. The first
* time this method is called we load up all of the folders
* under the store's defaultFolder
*/
public int getChildCount() {
if (folder == null) {
loadChildren();
}
return super.getChildCount();
}
protected void loadChildren() {
try {
// connect to the Store if we need to
if (!store.isConnected()) {
store.connect();
}
// get the default folder, and list the
// subscribed folders on it
folder = store.getDefaultFolder();
// Folder[] sub = folder.listSubscribed();
Folder[] sub = folder.list();
// add a FolderTreeNode for each Folder
int num = sub.length;
for(int i = 0; i < num; i++) {
FolderTreeNode node = new FolderTreeNode(sub[i]);
// we used insert here, since add() would make
// another recursive call to getChildCount();
insert(node, i);
}
} catch (MessagingException me) {
me.printStackTrace();
}
}
/**
* We override toString() so we can display the store URLName
* without the password.
*/
public String toString() {
if (display == null) {
URLName url = store.getURLName();
if (url == null) {
display = store.toString();
} else {
// don't show the password
URLName too = new URLName( url.getProtocol(), url.getHost(), url.getPort(),
url.getFile(), url.getUsername(), null);
display = too.toString();
}
}
return display;
}
}

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.*;
import java.io.*;
import java.beans.*;
import javax.activation.*;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
/**
* A very simple TextViewer Bean for the MIMEType "text/plain"
*
* @author Christopher Cotton
*/
public class TextViewer extends JPanel implements CommandObject
{
private JTextArea text_area = null;
private DataHandler dh = null;
private String verb = null;
/**
* Constructor
*/
public TextViewer() {
super(new GridLayout(1,1));
// create the text area
text_area = new JTextArea();
text_area.setEditable(false);
text_area.setLineWrap(true);
// create a scroll pane for the JTextArea
JScrollPane sp = new JScrollPane();
sp.setPreferredSize(new Dimension(300, 300));
sp.getViewport().add(text_area);
add(sp);
}
public void setCommandContext(String verb, DataHandler dh)
throws IOException {
this.verb = verb;
this.dh = dh;
this.setInputStream( dh.getInputStream() );
}
/**
* set the data stream, component to assume it is ready to
* be read.
*/
public void setInputStream(InputStream ins) {
int bytes_read = 0;
// check that we can actually read
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte data[] = new byte[1024];
try {
while((bytes_read = ins.read(data)) >0)
baos.write(data, 0, bytes_read);
ins.close();
} catch(Exception e) {
e.printStackTrace();
}
// convert the buffer into a string
// place in the text area
text_area.setText(baos.toString());
}
}

View File

@ -0,0 +1,9 @@
#
# Example command map, using the MailcapCommandMap.
#
# for our viewers
#
message/*;; x-java-view=MessageViewer
text/plain;; x-java-view=TextViewer
multipart/*;; x-java-view=MultipartViewer

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 1996-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
*
* @author Christopher Cotton
*/
import javax.mail.*;
/**
* copier will copy a specified number of messages from one folder
* to another folder. it demonstrates how to use the JavaMail APIs
* to copy messages.<p>
*
* Usage for copier: copier <i>store urlname</i>
* <i>src folder</i> <i>dest folder</i> <i>start msg #</i> <i>end msg #</i><p>
*
*/
public class copier {
public static void main(String argv[]) {
boolean debug = false; // change to get more errors
if (argv.length != 5) {
System.out.println( "usage: copier <urlname> <src folder>" +
"<dest folder> <start msg #> <end msg #>");
return;
}
try {
URLName url = new URLName(argv[0]);
String src = argv[1]; // source folder
String dest = argv[2]; // dest folder
int start = Integer.parseInt(argv[3]); // copy from message #
int end = Integer.parseInt(argv[4]); // to message #
// Get the default Session object
Session session = Session.getInstance(System.getProperties(), null);
// session.setDebug(debug);
// Get a Store object that implements the protocol.
Store store = session.getStore(url);
store.connect();
System.out.println("Connected...");
// Open Source Folder
Folder folder = store.getFolder(src);
folder.open(Folder.READ_WRITE);
System.out.println("Opened source...");
if (folder.getMessageCount() == 0) {
System.out.println("Source folder has no messages ..");
folder.close(false);
store.close();
}
// Open destination folder, create if needed
Folder dfolder = store.getFolder(dest);
if (!dfolder.exists()) // create
dfolder.create(Folder.HOLDS_MESSAGES);
Message[] msgs = folder.getMessages(start, end);
System.out.println("Got messages...");
// Copy messages into destination,
folder.copyMessages(msgs, dfolder);
System.out.println("Copied messages...");
// Close the folder and store
folder.close(false);
store.close();
System.out.println("Closed folder and store...");
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}

View File

@ -0,0 +1,185 @@
/*
* Copyright (c) 1996-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.Properties;
import javax.mail.*;
import com.sun.mail.imap.*;
/**
* Demo app that exercises the Message interfaces.
* List information about folders.
*
* @author John Mani
* @author Bill Shannon
*/
public class folderlist {
static String protocol = null;
static String host = null;
static String user = null;
static String password = null;
static String url = null;
static String root = null;
static String pattern = "%";
static boolean recursive = false;
static boolean verbose = false;
static boolean debug = false;
public static void main(String argv[]) throws Exception {
int optind;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-R")) {
root = argv[++optind];
} else if (argv[optind].equals("-r")) {
recursive = true;
} else if (argv[optind].equals("-v")) {
verbose = true;
} else if (argv[optind].equals("-D")) {
debug = true;
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: folderlist [-T protocol] [-H host] [-U user] [-P password] [-L url]");
System.out.println(
"\t[-R root] [-r] [-v] [-D] [pattern]");
System.exit(1);
} else {
break;
}
}
if (optind < argv.length)
pattern = argv[optind];
// Get a Properties object
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getInstance(props, null);
session.setDebug(debug);
// Get a Store object
Store store = null;
Folder rf = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, user, password);
else
store.connect();
}
// List namespace
if (root != null)
rf = store.getFolder(root);
else
rf = store.getDefaultFolder();
dumpFolder(rf, false, "");
if ((rf.getType() & Folder.HOLDS_FOLDERS) != 0) {
Folder[] f = rf.list(pattern);
for (int i = 0; i < f.length; i++)
dumpFolder(f[i], recursive, " ");
}
store.close();
}
static void dumpFolder(Folder folder, boolean recurse, String tab)
throws Exception {
System.out.println(tab + "Name: " + folder.getName());
System.out.println(tab + "Full Name: " + folder.getFullName());
System.out.println(tab + "URL: " + folder.getURLName());
if (verbose) {
if (!folder.isSubscribed())
System.out.println(tab + "Not Subscribed");
if ((folder.getType() & Folder.HOLDS_MESSAGES) != 0) {
if (folder.hasNewMessages())
System.out.println(tab + "Has New Messages");
System.out.println(tab + "Total Messages: " +
folder.getMessageCount());
System.out.println(tab + "New Messages: " +
folder.getNewMessageCount());
System.out.println(tab + "Unread Messages: " +
folder.getUnreadMessageCount());
}
if ((folder.getType() & Folder.HOLDS_FOLDERS) != 0)
System.out.println(tab + "Is Directory");
/*
* Demonstrate use of IMAP folder attributes
* returned by the IMAP LIST response.
*/
if (folder instanceof IMAPFolder) {
IMAPFolder f = (IMAPFolder)folder;
String[] attrs = f.getAttributes();
if (attrs != null && attrs.length > 0) {
System.out.println(tab + "IMAP Attributes:");
for (int i = 0; i < attrs.length; i++)
System.out.println(tab + " " + attrs[i]);
}
}
}
System.out.println();
if ((folder.getType() & Folder.HOLDS_FOLDERS) != 0) {
if (recurse) {
Folder[] f = folder.list();
for (int i = 0; i < f.length; i++)
dumpFolder(f[i], recurse, tab + " ");
}
}
}
}

View File

@ -0,0 +1,329 @@
/*
* Copyright (c) 2009-2017 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009-2017 Jason Mehrens. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.logging.ErrorManager;
import java.util.logging.Level;
import java.util.logging.LogManager;
/**
* An error manager used to store mime messages from the <tt>MailHandler</tt>
* to the file system when the email server is unavailable or unreachable. The
* code to manually setup this error manager can be as simple as the following:
* <pre>
* File dir = new File("path to dir");
* FileErrorManager em = new FileErrorManager(dir);
* </pre>
*
* <p>
* <b>Configuration:</b>
* The code to setup this error manager via the logging properties can be as
* simple as the following:
* <pre>
* #Default FileErrorManager settings.
* FileErrorManager.pattern = path to directory
* </pre>
*
* If properties are not defined, or contain invalid values, then the specified
* default values are used.
* <ul>
* <li>FileErrorManager.pattern the absolute file path to the directory which
* will store any failed email messages. (defaults to the value of the system
* property <tt>java.io.tmpdir</tt>)
* </ul>
*
* @author Jason Mehrens
*/
public class FileErrorManager extends ErrorManager {
/**
* Stores the LogManager.
*/
private static final LogManager manager = LogManager.getLogManager();
/**
* Used to report errors that this error manager fails to report.
*/
private final ErrorManager next = new ErrorManager();
/**
* Directory of the email store.
*/
private final File emailStore;
/**
* Creates a new error manager. Files are stored in the users temp
* directory.
*
* @exception SecurityException if unable to access system properties or if
* a security manager is present and unable to read or write to users temp
* directory.
*/
public FileErrorManager() {
this.emailStore = getEmailStore();
init();
}
/**
* Creates a new error manager.
*
* @param dir a directory to store the email files.
* @throws NullPointerException if <tt>dir</tt> is <tt>null</tt>
* @throws IllegalArgumentException if <tt>dir</tt> is a
* <tt>java.io.File</tt> subclass, not a directory, or is not an absolute
* path.
* @throws SecurityException if a security manager is present and unable to
* read or write to a given directory.
*/
public FileErrorManager(File dir) {
this.emailStore = dir;
init();
}
/**
* If the message parameter is a raw email, and passes the store term, then
* this method will store the email to the file system. If the message
* parameter is not a raw email then the message is forwarded to the super
* class. If an email is written to the file system without error, then the
* original reported error is ignored.
*
* @param msg String raw email or plain error message.
* @param ex Exception that occurred in the mail handler.
* @param code int error manager code.
*/
@Override
public void error(String msg, Exception ex, int code) {
if (isRawEmail(msg)) {
try {
storeEmail(msg);
} catch (final IOException | RuntimeException IOE) {
next.error(msg, ex, code);
super.error(emailStore.toString(), IOE, ErrorManager.GENERIC_FAILURE);
}
} else {
next.error(msg, ex, code);
}
}
/**
* Performs the initialization for this object.
*/
private void init() {
if (next == null) {
throw new NullPointerException(ErrorManager.class.getName());
}
File dir = this.emailStore;
if (dir.getClass() != File.class) { //For security reasons.
throw new IllegalArgumentException(dir.getClass().getName());
}
if (!dir.isDirectory()) {
throw new IllegalArgumentException("File must be a directory.");
}
if (!dir.canWrite()) { //Can throw under a security manager.
super.error(dir.getAbsolutePath(),
new SecurityException("write"), ErrorManager.OPEN_FAILURE);
}
//For now, only absolute paths are allowed.
if (!dir.isAbsolute()) {
throw new IllegalArgumentException("Only absolute paths are allowed.");
}
if (!dir.canRead()) { //Can throw under a security manager.
super.error(dir.getAbsolutePath(),
new SecurityException("read"), ErrorManager.OPEN_FAILURE);
}
}
/**
* Creates a common temp file prefix.
*
* @return the file prefix.
*/
private String prefixName() {
return "FileErrorManager";
}
/**
* Creates a common temp file suffix.
*
* @return the file suffix.
*/
private String suffixName() {
return ".eml";
}
/**
* Determines if the given message is a MIME message or just free text.
*
* @param msg the message to examine.
* @return true if MIME message otherwise false.
*/
private boolean isRawEmail(String msg) {
if (msg != null && msg.length() > 0) {
return !msg.startsWith(Level.SEVERE.getName());
}
return false;
}
/**
* Stores the given string in a file.
*
* @param email the message to store.
* @throws IOException if there is a problem.
*/
private void storeEmail(String email) throws IOException {
File tmp = null;
FileOutputStream out = null;
for (;;) {
tmp = File.createTempFile(prefixName(), suffixName(), emailStore);
try {
out = new FileOutputStream(tmp);
break;
} catch (FileNotFoundException FNFE) {
if (!tmp.exists()) { //retry if file is locked
throw FNFE;
}
}
}
try (PrintStream ps = new PrintStream(wrap(out), false, "UTF-8")) {
ps.print(email);
ps.flush();
tmp = null; //Don't delete 'tmp' if all bytes were written.
} finally {
close(out);
delete(tmp); //Only deletes if not null.
}
}
/**
* Null safe close method.
*
* @param out closes the given stream.
*/
private void close(OutputStream out) {
if (out != null) {
try {
out.close();
} catch (IOException IOE) {
super.error(out.toString(), IOE, ErrorManager.CLOSE_FAILURE);
}
}
}
/**
* Null safe delete method.
*
* @param tmp the file to delete.
*/
private void delete(File tmp) {
if (tmp != null) {
try {
if (!tmp.delete() && tmp.exists()) {
try {
try {
tmp.deleteOnExit();
} catch (final LinkageError shutdown) {
throw new RuntimeException(shutdown);
}
} catch (final RuntimeException shutdown) {
if (!tmp.delete()) {
super.error(tmp.getAbsolutePath(), shutdown,
ErrorManager.CLOSE_FAILURE);
}
}
}
} catch (SecurityException SE) {
super.error(tmp.toString(), SE, ErrorManager.CLOSE_FAILURE);
}
}
}
/**
* Gets the location of the email store.
*
* @return the File location.
*/
private File getEmailStore() {
String dir = manager.getProperty(
getClass().getName().concat(".pattern"));
if (dir == null) {
dir = AccessController.doPrivileged(new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty("java.io.tmpdir", ".");
}
});
}
return new File(dir);
}
/**
* Wraps the given stream as a NewLineOutputStream.
*
* @param out the stream to wrap.
* @return the original or wrapped output stream.
*/
@SuppressWarnings("UseSpecificCatch")
private OutputStream wrap(OutputStream out) {
assert out != null;
Class<?> k;
try {
k = Class.forName("NewlineOutputStream");
if (OutputStream.class.isAssignableFrom(k)) {
Constructor<?> c = k.getConstructor(OutputStream.class);
return (OutputStream) c.newInstance(out);
} else {
super.error("Unable to switch newlines",
new ClassNotFoundException(k.getName()),
ErrorManager.GENERIC_FAILURE);
}
} catch (RuntimeException re) {
super.error("Unable to switch newlines",
re, ErrorManager.GENERIC_FAILURE);
} catch (Exception ex) {
super.error("Unable to switch newlines",
ex, ErrorManager.GENERIC_FAILURE);
} catch (LinkageError le) {
super.error("Unable to switch newlines",
new ClassNotFoundException("", le),
ErrorManager.GENERIC_FAILURE);
}
return out;
}
}

View File

@ -0,0 +1,668 @@
/*
* Copyright (c) 2009-2016 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009-2016 Jason Mehrens. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import com.sun.mail.util.logging.CollectorFormatter;
import com.sun.mail.util.logging.DurationFilter;
import com.sun.mail.util.logging.MailHandler;
import com.sun.mail.util.logging.SeverityComparator;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.util.*;
import java.util.logging.*;
import javax.activation.DataHandler;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
/**
* Demo for the different configurations for the MailHandler. If the logging
* properties file or class is not specified then this demo will apply some
* default settings to store emails in the user's temp directory.
*
* @author Jason Mehrens
*/
public class MailHandlerDemo {
/**
* This class name.
*/
private static final String CLASS_NAME = MailHandlerDemo.class.getName();
/**
* The logger for this class name.
*/
private static final Logger LOGGER = Logger.getLogger(CLASS_NAME);
/**
* Runs the demo.
*
* @param args the command line arguments
* @throws IOException if there is a problem.
*/
public static void main(String[] args) throws IOException {
List<String> l = Arrays.asList(args);
if (l.contains("/?") || l.contains("-?") || l.contains("-help")) {
LOGGER.info("Usage: java MailHandlerDemo "
+ "[[-all] | [-body] | [-custom] | [-debug] | [-low] "
+ "| [-simple] | [-pushlevel] | [-pushfilter] "
+ "| [-pushnormal] | [-pushonly]] "
+ "\n\n"
+ "-all\t\t: Execute all demos.\n"
+ "-body\t\t: An email with all records and only a body.\n"
+ "-custom\t\t: An email with attachments and dynamic names.\n"
+ "-debug\t\t: Output basic debug information about the JVM "
+ "and log configuration.\n"
+ "-low\t\t: Generates multiple emails due to low capacity."
+ "\n"
+ "-simple\t\t: An email with all records with body and "
+ "an attachment.\n"
+ "-pushlevel\t: Generates high priority emails when the"
+ " push level is triggered and normal priority when "
+ "flushed.\n"
+ "-pushFilter\t: Generates high priority emails when the "
+ "push level and the push filter is triggered and normal "
+ "priority emails when flushed.\n"
+ "-pushnormal\t: Generates multiple emails when the "
+ "MemoryHandler push level is triggered. All generated "
+ "email are sent as normal priority.\n"
+ "-pushonly\t: Generates multiple emails when the "
+ "MemoryHandler push level is triggered. Generates high "
+ "priority emails when the push level is triggered and "
+ "normal priority when flushed.\n");
} else {
final boolean debug = init(l); //may create log messages.
try {
LOGGER.log(Level.FINEST, "This is the finest part of the demo.",
new MessagingException("Fake JavaMail issue."));
LOGGER.log(Level.FINER, "This is the finer part of the demo.",
new NullPointerException("Fake bug."));
LOGGER.log(Level.FINE, "This is the fine part of the demo.");
LOGGER.log(Level.CONFIG, "Logging config file is {0}.",
getConfigLocation());
LOGGER.log(Level.INFO, "Your temp directory is {0}, "
+ "please wait...", getTempDir());
try { //Waste some time for the custom formatter.
Thread.sleep(3L * 1000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
LOGGER.log(Level.WARNING, "This is a warning.",
new FileNotFoundException("Fake file chooser issue."));
LOGGER.log(Level.SEVERE, "The end of the demo.",
new IOException("Fake access denied issue."));
} finally {
closeHandlers();
}
//Force parse errors. This does have side effects.
if (debug && getConfigLocation() != null) {
LogManager.getLogManager().readConfiguration();
}
}
}
/**
* Used debug problems with the logging.properties. The system property
* java.security.debug=access,stack can be used to trace access to the
* LogManager reset.
*
* @param prefix a string to prefix the output.
* @param err any PrintStream or null for System.out.
*/
@SuppressWarnings("UseOfSystemOutOrSystemErr")
private static void checkConfig(String prefix, PrintStream err) {
if (prefix == null || prefix.trim().length() == 0) {
prefix = "DEBUG";
}
if (err == null) {
err = System.out;
}
try {
err.println(prefix + ": java.version="
+ System.getProperty("java.version"));
err.println(prefix + ": LOGGER=" + LOGGER.getLevel());
err.println(prefix + ": JVM id "
+ ManagementFactory.getRuntimeMXBean().getName());
err.println(prefix + ": java.security.debug="
+ System.getProperty("java.security.debug"));
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
err.println(prefix + ": SecurityManager.class="
+ sm.getClass().getName());
err.println(prefix + ": SecurityManager classLoader="
+ toString(sm.getClass().getClassLoader()));
err.println(prefix + ": SecurityManager.toString=" + sm);
} else {
err.println(prefix + ": SecurityManager.class=null");
err.println(prefix + ": SecurityManager.toString=null");
err.println(prefix + ": SecurityManager classLoader=null");
}
String policy = System.getProperty("java.security.policy");
if (policy != null) {
File f = new File(policy);
err.println(prefix + ": AbsolutePath=" + f.getAbsolutePath());
err.println(prefix + ": CanonicalPath=" + f.getCanonicalPath());
err.println(prefix + ": length=" + f.length());
err.println(prefix + ": canRead=" + f.canRead());
err.println(prefix + ": lastModified="
+ new java.util.Date(f.lastModified()));
}
LogManager manager = LogManager.getLogManager();
String key = "java.util.logging.config.file";
String cfg = System.getProperty(key);
if (cfg != null) {
err.println(prefix + ": " + cfg);
File f = new File(cfg);
err.println(prefix + ": AbsolutePath=" + f.getAbsolutePath());
err.println(prefix + ": CanonicalPath=" + f.getCanonicalPath());
err.println(prefix + ": length=" + f.length());
err.println(prefix + ": canRead=" + f.canRead());
err.println(prefix + ": lastModified="
+ new java.util.Date(f.lastModified()));
} else {
err.println(prefix + ": " + key
+ " is not set as a system property.");
}
err.println(prefix + ": LogManager.class="
+ manager.getClass().getName());
err.println(prefix + ": LogManager classLoader="
+ toString(manager.getClass().getClassLoader()));
err.println(prefix + ": LogManager.toString=" + manager);
err.println(prefix + ": MailHandler classLoader="
+ toString(MailHandler.class.getClassLoader()));
err.println(prefix + ": Context ClassLoader="
+ toString(Thread.currentThread().getContextClassLoader()));
err.println(prefix + ": Session ClassLoader="
+ toString(Session.class.getClassLoader()));
err.println(prefix + ": DataHandler ClassLoader="
+ toString(DataHandler.class.getClassLoader()));
final String p = MailHandler.class.getName();
key = p.concat(".mail.to");
String to = manager.getProperty(key);
err.println(prefix + ": TO=" + to);
if (to != null) {
err.println(prefix + ": TO="
+ Arrays.toString(InternetAddress.parse(to, true)));
}
key = p.concat(".mail.from");
String from = manager.getProperty(key);
if (from == null || from.length() == 0) {
Session session = Session.getInstance(new Properties());
InternetAddress local = InternetAddress.getLocalAddress(session);
err.println(prefix + ": FROM=" + local);
} else {
err.println(prefix + ": FROM="
+ Arrays.asList(InternetAddress.parse(from, false)));
err.println(prefix + ": FROM="
+ Arrays.asList(InternetAddress.parse(from, true)));
}
synchronized (manager) {
final Enumeration<String> e = manager.getLoggerNames();
while (e.hasMoreElements()) {
final Logger l = manager.getLogger(e.nextElement());
if (l != null) {
final Handler[] handlers = l.getHandlers();
if (handlers.length > 0) {
err.println(prefix + ": " + l.getClass().getName()
+ ", " + l.getName());
for (Handler h : handlers) {
err.println(prefix + ":\t" + toString(prefix, err, h));
}
}
}
}
}
} catch (Throwable error) {
err.print(prefix + ": ");
error.printStackTrace(err);
}
err.flush();
}
/**
* Gets the class loader list.
*
* @param cl the class loader or null.
* @return the class loader list.
*/
private static String toString(ClassLoader cl) {
StringBuilder buf = new StringBuilder();
buf.append(cl);
while (cl != null) {
cl = cl.getParent();
buf.append("<-").append(cl);
}
return buf.toString();
}
/**
* Gets a formatting string describing the given handler.
*
* @param prefix the output prefix.
* @param err the error stream.
* @param h the handler.
* @return the formatted string.
*/
private static String toString(String prefix, PrintStream err, Handler h) {
StringBuilder buf = new StringBuilder();
buf.append(h.getClass().getName());
try {
if (h instanceof MailHandler) {
MailHandler mh = (MailHandler) h;
buf.append(", ").append(mh.getSubject());
}
} catch (SecurityException error) {
err.print(prefix + ": ");
error.printStackTrace(err);
}
try {
buf.append(", ").append(h.getFormatter());
} catch (SecurityException error) {
err.print(prefix + ": ");
error.printStackTrace(err);
}
try {
if (h instanceof MailHandler) {
MailHandler mh = (MailHandler) h;
buf.append(", ").append(Arrays.toString(
mh.getAttachmentFormatters()));
}
} catch (SecurityException error) {
err.print(prefix + ": ");
error.printStackTrace(err);
}
try {
buf.append(", ").append(h.getLevel());
} catch (SecurityException error) {
err.print(prefix + ": ");
error.printStackTrace(err);
}
try {
buf.append(", ").append(h.getFilter());
} catch (SecurityException error) {
err.print(prefix + ": ");
error.printStackTrace(err);
}
try {
buf.append(", ").append(h.getErrorManager());
} catch (SecurityException error) {
err.print(prefix + ": ");
error.printStackTrace(err);
}
buf.append(", ").append(toString(h.getClass().getClassLoader()));
return buf.toString();
}
/**
* Example for body only messages. On close the remaining messages are sent. <code>
* ##logging.properties
* MailHandlerDemo.handlers=com.sun.mail.util.logging.MailHandler
* com.sun.mail.util.logging.MailHandler.subject=Body only demo
* ##
* </code>
*/
private static void initBodyOnly() {
MailHandler h = new MailHandler();
h.setSubject("Body only demo");
LOGGER.addHandler(h);
}
/**
* Example showing that when the mail handler reaches capacity it will
* format and send the current records. Capacity is used to roughly limit
* the size of an outgoing message. On close any remaining messages are
* sent. <code>
* ##logging.properties
* MailHandlerDemo.handlers=com.sun.mail.util.logging.MailHandler
* com.sun.mail.util.logging.MailHandler.subject=Low capacity demo
* com.sun.mail.util.logging.MailHandler.capacity=5
* ##
* </code>
*/
private static void initLowCapacity() {
MailHandler h = new MailHandler(5);
h.setSubject("Low capacity demo");
LOGGER.addHandler(h);
}
/**
* Example for body only messages. On close any remaining messages are sent. <code>
* ##logging.properties
* MailHandlerDemo.handlers=com.sun.mail.util.logging.MailHandler
* com.sun.mail.util.logging.MailHandler.subject=Body and attachment demo
* com.sun.mail.util.logging.MailHandler.attachment.formatters=java.util.logging.XMLFormatter
* com.sun.mail.util.logging.MailHandler.attachment.names=data.xml
* ##
* </code>
*/
private static void initSimpleAttachment() {
MailHandler h = new MailHandler();
h.setSubject("Body and attachment demo");
h.setAttachmentFormatters(new XMLFormatter());
h.setAttachmentNames("data.xml");
LOGGER.addHandler(h);
}
/**
* Example setup for priority messages by level. If the push level is
* triggered the message is high priority. Otherwise, on close any remaining
* messages are sent. <code>
* ##logging.properties
* MailHandlerDemo.handlers=com.sun.mail.util.logging.MailHandler
* com.sun.mail.util.logging.MailHandler.subject=Push level demo
* com.sun.mail.util.logging.MailHandler.pushLevel=WARNING
* ##
* </code>
*/
private static void initWithPushLevel() {
MailHandler h = new MailHandler();
h.setSubject("Push level demo");
h.setPushLevel(Level.WARNING);
LOGGER.addHandler(h);
}
/**
* Example for priority messages by generation rate. If the push filter is
* triggered the message is high priority. Otherwise, on close any remaining
* messages are sent. If the capacity is set to the <code>
* ##logging.properties
* MailHandlerDemo.handlers=com.sun.mail.util.logging.MailHandler
* com.sun.mail.util.logging.MailHandler.subject=Push filter demo
* com.sun.mail.util.logging.MailHandler.pushLevel=ALL
* com.sun.mail.util.logging.MailHandler.pushFilter=com.sun.mail.util.logging.DurationFilter
* com.sun.mail.util.logging.DurationFilter.records=2
* com.sun.mail.util.logging.DurationFilter.duration=1 * 60 * 1000
* ##
* </code>
*/
private static void initWithPushFilter() {
MailHandler h = new MailHandler();
h.setSubject("Push filter demo");
h.setPushLevel(Level.ALL);
h.setPushFilter(new DurationFilter(2, 1L * 60L * 1000L));
LOGGER.addHandler(h);
}
/**
* Example for circular buffer behavior. The level, push level, and capacity
* are set the same so that the memory handler push results in a mail
* handler push. All messages are high priority. On close any remaining
* records are discarded because they never reach the mail handler. <code>
* ##logging.properties
* MailHandlerDemo.handlers=java.util.logging.MemoryHandler
* java.util.logging.MemoryHandler.target=com.sun.mail.util.logging.MailHandler
* com.sun.mail.util.logging.MailHandler.level=ALL
* java.util.logging.MemoryHandler.level=ALL
* java.util.logging.MemoryHandler.push=WARNING
* com.sun.mail.util.logging.MailHandler.subject=Push only demo
* com.sun.mail.util.logging.MailHandler.pushLevel=WARNING
* ##
* </code>
*/
private static void initPushOnly() {
final int capacity = 3;
final Level pushLevel = Level.WARNING;
final MailHandler h = new MailHandler(capacity);
h.setPushLevel(pushLevel);
h.setSubject("Push only demo");
MemoryHandler m = new MemoryHandler(h, capacity, pushLevel);
h.setLevel(m.getLevel());
LOGGER.addHandler(m);
pushOnlyHandler = h;
}
/**
* Holds on to the push only handler. Only declared here to apply fallback
* settings.
*/
private static Handler pushOnlyHandler;
/**
* Example for circular buffer behavior as normal priority. The push level,
* and capacity are set the same so that the memory handler push results in
* a mail handler push. All messages are normal priority. On close any
* remaining records are discarded because they never reach the mail
* handler. Use the LogManager config option or extend the MemoryHandler to
* emulate this behavior via the logging.properties.
*/
private static void initPushNormal() {
final int capacity = 3;
final MailHandler h = new MailHandler(capacity);
h.setSubject("Push normal demo");
MemoryHandler m = new MemoryHandler(h, capacity, Level.WARNING) {
@Override
public void push() {
super.push(); //push to target.
super.flush(); //make the target send the email.
}
};
LOGGER.addHandler(m);
pushNormalHandler = h;
}
/**
* Holds on to the push normal handler. Only declared here to apply fallback
* settings.
*/
private static Handler pushNormalHandler;
/**
* Example for various kinds of custom sorting, formatting, and filtering
* for multiple attachment messages. The subject will contain the most
* severe record and a count of remaining records. The log records are
* ordered from most severe to least severe. The body uses a custom
* formatter that includes a summary by date and time. The attachment use
* XML and plain text formats. Each attachment has a different set of
* filtering. The attachment names are generated from either a fixed name or
* are built using the number and type of the records formatted. On close
* any remaining messages are sent. Use the LogManager config option or
* extend the MemoryHandler to emulate this behavior via the
* logging.properties.
*/
private static void initCustomAttachments() {
MailHandler h = new MailHandler();
//Sort records by severity keeping the severe messages at the top.
h.setComparator(Collections.reverseOrder(new SeverityComparator()));
//Use subject to provide a hint as to what is in the email.
h.setSubject(new CollectorFormatter());
//Make the body give a simple summary of what happened.
h.setFormatter(new SummaryFormatter());
//Create 3 attachments.
h.setAttachmentFormatters(new XMLFormatter(),
new XMLFormatter(), new SimpleFormatter());
//Filter each attachment differently.
h.setAttachmentFilters(null,
new DurationFilter(3L, 1000L),
new DurationFilter(1L, 15L * 60L * 1000L));
//Creating the attachment name formatters.
h.setAttachmentNames(new CollectorFormatter("all.xml"),
new CollectorFormatter("{3} records and {5} errors.xml"),
new CollectorFormatter("{5,choice,0#no errors|1#1 error|1<"
+ "{5,number,integer} errors}.txt"));
LOGGER.addHandler(h);
}
/**
* Sets up the demos that will run.
*
* @param l the list of arguments.
* @return true if debug is on.
*/
private static boolean init(List<String> l) {
l = new ArrayList<String>(l);
Session session = Session.getInstance(System.getProperties());
boolean all = l.remove("-all") || l.isEmpty();
if (l.remove("-body") || all) {
initBodyOnly();
}
if (l.remove("-custom") || all) {
initCustomAttachments();
}
if (l.remove("-low") || all) {
initLowCapacity();
}
if (l.remove("-pushfilter") || all) {
initWithPushFilter();
}
if (l.remove("-pushlevel") || all) {
initWithPushLevel();
}
if (l.remove("-pushnormal") || all) {
initPushNormal();
}
if (l.remove("-pushonly") || all) {
initPushOnly();
}
if (l.remove("-simple") || all) {
initSimpleAttachment();
}
boolean fallback = applyFallbackSettings();
boolean debug = l.remove("-debug") || session.getDebug();
if (debug) {
checkConfig(CLASS_NAME, session.getDebugOut());
}
if (!l.isEmpty()) {
LOGGER.log(Level.SEVERE, "Unknown commands: {0}", l);
}
if (fallback) {
LOGGER.info("Check your user temp dir for output.");
}
return debug;
}
/**
* Close and remove all handlers added to the class logger.
*/
private static void closeHandlers() {
Handler[] handlers = LOGGER.getHandlers();
for (Handler h : handlers) {
h.close();
LOGGER.removeHandler(h);
}
}
/**
* Apply some fallback settings if no configuration file was specified.
*
* @return true if fallback settings were applied.
*/
private static boolean applyFallbackSettings() {
if (getConfigLocation() == null) {
LOGGER.setLevel(Level.ALL);
Handler[] handlers = LOGGER.getHandlers();
for (Handler h : handlers) {
fallbackSettings(h);
}
fallbackSettings(pushOnlyHandler);
fallbackSettings(pushNormalHandler);
return true;
}
return false;
}
/**
* Common fallback settings for a single handler.
*
* @param h the handler.
*/
private static void fallbackSettings(Handler h) {
if (h != null) {
h.setErrorManager(new FileErrorManager());
h.setLevel(Level.ALL);
}
}
/**
* Gets the system temp directory.
*
* @return the system temp directory.
*/
private static String getTempDir() {
return System.getProperty("java.io.tmpdir");
}
/**
* Gets the configuration file or class name.
*
* @return the file name or class name.
*/
private static String getConfigLocation() {
String file = System.getProperty("java.util.logging.config.file");
if (file == null) {
return System.getProperty("java.util.logging.config.class");
}
return file;
}
/**
* No objects are allowed.
* @throws IllegalAccessException always.
*/
private MailHandlerDemo() throws IllegalAccessException {
throw new IllegalAccessException();
}
}

View File

@ -0,0 +1,103 @@
Logging Demo
------------
Notes:
======
This should not be taken as a demo of how to use the logging API, but
rather how to use the features of the MailHandler.
To run the demo:
================
1. The demo requires Java version 1.5 or newer.
We *strongly* encourage you to use the latest version of J2SE,
which you can download from
http://www.oracle.com/technetwork/java/javase/downloads.
2. Set your CLASSPATH to include the "mail.jar" and "activation.jar".
For JDK 1.1 on UNIX:
export CLASSPATH=/u/me/download/mail.jar:/u/me/download/activation.jar.
For JDK 1.2 and newer on UNIX:
export CLASSPATH=/u/me/download/mail.jar:/u/me/download/activation.jar:.
3. Go to the demo/logging directory
4. Compile all the files using your Java compiler. For example:
javac *.java
5. Not required but, you should edit the maildemo.properties and change the
mail.to address and mail.host to your mail server ip or host name.
6. Run the demo. For example:
java -Dmail.debug=false -Djava.util.logging.config.file=/u/me/download/javamail/demo/maildemo.properties MailHandlerDemo
Overview of the Classes
=======================
Main Classes:
MailHandlerDemo = The main method creates log messages
for the MailHander to capture. The
initXXX methods describe some of the
common setup code for different types
of email messages.
Usage: java MailHandlerDemo [[-all] | [-body] | [-debug]
| [-low] | [-simple] | [-pushlevel]
| [-pushfilter] | [-pushnormal]| [-pushonly]]
Options:
-all : Execute all demos.
-body : An email with all records and only a body.
-custom : An email with attachments and dynamic names.
-debug : Output basic debug information about the
JVM and log configuration.
-low : Generates multiple emails due to low
capacity.
-simple : An email with all records with body and an
attachment.
-pushlevel : Generates high priority emails when
the push level is triggered and
normal priority when flushed.
-pushFilter : Generates high priority emails when
the push level and the push filter
is triggered and normal priority
emails when flushed.
-pushnormal : Generates multiple emails when the
MemoryHandler push level is
triggered. All generated email are
sent as normal priority.
-pushonly : Generates multiple emails when the
MemoryHandler push level is
triggered. Generates high priority
emails when the push level is
triggered and normal priority when
flushed.
FileErrorManager = Used to store email messages to the
local file system when mail transport
fails. This is installed as a
fallback in case the logging config is
not specified.
SummaryFormatter = An example compact formatter with summary
for use with the body of an email message.
Support files:
maildemo.properties = A sample LogManager properties file for
the MailHandlerDemo.
maildemo.policy = A sample security policy file to use with
the MailHandlerDemo. This can be used to
enable security tracing.

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2009-2014 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009-2014 Jason Mehrens. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import com.sun.mail.util.logging.CollectorFormatter;
import com.sun.mail.util.logging.CompactFormatter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
/**
* A compact formatter used to summarize an error report.
*
* @author Jason Mehrens
*/
public final class SummaryFormatter extends Formatter {
/**
* The line formatter.
*/
private final CompactFormatter format;
/**
* The footer formatter.
*/
private final CollectorFormatter footer;
/**
* Creates the formatter.
*/
public SummaryFormatter() {
format = new CompactFormatter("[%4$s]\t%5$s %6$s%n");
footer = new CollectorFormatter("\nThese {3} messages occurred between "
+ "{7,time,EEE, MMM dd HH:mm:ss:S ZZZ yyyy} and "
+ "{8,time,EEE, MMM dd HH:mm:ss:S ZZZ yyyy}\n", format, null);
}
/**
* Gets the header information.
*
* @param h the handler or null.
* @return the header.
*/
@Override
public String getHead(Handler h) {
footer.getHead(h);
return format.getHead(h);
}
/**
* Formats the given record.
*
* @param record the log record.
* @return the formatted record.
* @throws NullPointerException if record is null.
*/
public String format(LogRecord record) {
String data = format.format(record);
footer.format(record); //Track record times for footer.
return data;
}
/**
* Gets and resets the footer information.
*
* @param h the handler or null.
* @return the footer.
*/
@Override
public String getTail(Handler h) {
format.getTail(h);
return footer.getTail(h);
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014 Jason Mehrens. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
grant {
permission java.util.logging.LoggingPermission "control";
permission java.util.PropertyPermission "*", "read, write";
permission java.net.SocketPermission "*", "resolve, connect";
permission java.lang.RuntimePermission "accessClassInPackage.sun.util.logging.resources";
permission java.io.FilePermission "<<ALL FILES>>", "read, write";
permission java.lang.RuntimePermission "getClassLoader";
};

View File

@ -0,0 +1,72 @@
#
# Copyright (c) 2009-2016 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009-2016 Jason Mehrens. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# - Neither the name of Oracle nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This can be used by setting the system property
# -Djava.util.logging.config.file=path to this file
# Taken from the JDK defaults.
handlers= java.util.logging.ConsoleHandler
.level= INFO
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# Set the mail handler demo logger level
MailHandlerDemo.level = ALL
# Configure the MailHandler.
com.sun.mail.util.logging.MailHandler.level = ALL
com.sun.mail.util.logging.MailHandler.mail.host = my-mail-server
com.sun.mail.util.logging.MailHandler.mail.from = me@example.com
com.sun.mail.util.logging.MailHandler.mail.to = me@example.com
com.sun.mail.util.logging.MailHandler.verify = local
# Add attachments if needed.
#com.sun.mail.util.logging.MailHandler.attachment.formatters = java.util.logging.SimpleFormatter, java.util.logging.XMLFormatter
# No filters.
#com.sun.mail.util.logging.MailHandler.attachment.filters = null, null
# Formatter class name or strings.
#com.sun.mail.util.logging.MailHandler.attachment.names = simple.txt, error.xml
# Store messages on error by installing the FileErrorManager (demo code).
com.sun.mail.util.logging.MailHandler.errorManager = FileErrorManager
# Configure the FileErrorManager for demo (not required).
# FileErrorManager.pattern = path-to-dir
# Debug mail transport issues.
mail.debug = false

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 1996-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.event.*;
import javax.activation.*;
import com.sun.mail.imap.*;
/* Monitors given mailbox for new mail */
public class monitor {
public static void main(String argv[]) {
if (argv.length != 5) {
System.out.println(
"Usage: monitor <host> <user> <password> <mbox> <freq>");
System.exit(1);
}
System.out.println("\nTesting monitor\n");
try {
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getInstance(props, null);
// session.setDebug(true);
// Get a Store object
Store store = session.getStore("imap");
// Connect
store.connect(argv[0], argv[1], argv[2]);
// Open a Folder
Folder folder = store.getFolder(argv[3]);
if (folder == null || !folder.exists()) {
System.out.println("Invalid folder");
System.exit(1);
}
folder.open(Folder.READ_WRITE);
// Add messageCountListener to listen for new messages
folder.addMessageCountListener(new MessageCountAdapter() {
public void messagesAdded(MessageCountEvent ev) {
Message[] msgs = ev.getMessages();
System.out.println("Got " + msgs.length + " new messages");
// Just dump out the new messages
for (int i = 0; i < msgs.length; i++) {
try {
System.out.println("-----");
System.out.println("Message " +
msgs[i].getMessageNumber() + ":");
msgs[i].writeTo(System.out);
} catch (IOException ioex) {
ioex.printStackTrace();
} catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
});
// Check mail once in "freq" MILLIseconds
int freq = Integer.parseInt(argv[4]);
boolean supportsIdle = false;
try {
if (folder instanceof IMAPFolder) {
IMAPFolder f = (IMAPFolder)folder;
f.idle();
supportsIdle = true;
}
} catch (FolderClosedException fex) {
throw fex;
} catch (MessagingException mex) {
supportsIdle = false;
}
for (;;) {
if (supportsIdle && folder instanceof IMAPFolder) {
IMAPFolder f = (IMAPFolder)folder;
f.idle();
System.out.println("IDLE done");
} else {
Thread.sleep(freq); // sleep for freq milliseconds
// This is to force the IMAP server to send us
// EXISTS notifications.
folder.getMessageCount();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 1996-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
/* MOVE messages between mailboxes */
public class mover {
static String protocol = "imap";
static String host = null;
static String user = null;
static String password = null;
static String src = null;
static String dest = null;
static boolean expunge = false;
static String url = null;
public static void main(String argv[]) {
int start = 1; int end = -1;
int optind;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) { // protocol
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) { // host
host = argv[++optind];
} else if (argv[optind].equals("-U")) { // user
user = argv[++optind];
} else if (argv[optind].equals("-P")) { // password
password = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-s")) { // Source mbox
src = argv[++optind];
} else if (argv[optind].equals("-d")) { // Destination mbox
dest = argv[++optind];
} else if (argv[optind].equals("-x")) { // Expunge ?
expunge = true;
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: mover [-T protocol] [-H host] [-U user] [-P password] [-L url] [-v]");
System.out.println(
"\t[-s source mbox] [-d destination mbox] [-x] [msgnum1] [msgnum2]");
System.out.println(
"\t The -x option => EXPUNGE deleted messages");
System.out.println(
"\t msgnum1 => start of message-range; msgnum2 => end of message-range");
System.exit(1);
} else {
break;
}
}
if (optind < argv.length)
start = Integer.parseInt(argv[optind++]); // start msg
if (optind < argv.length)
end = Integer.parseInt(argv[optind++]); // end msg
try {
// Get a Properties object
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getInstance(props, null);
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, user, password);
else
store.connect();
}
// Open source Folder
Folder folder = store.getFolder(src);
if (folder == null || !folder.exists()) {
System.out.println("Invalid folder: " + src);
System.exit(1);
}
folder.open(Folder.READ_WRITE);
int count = folder.getMessageCount();
if (count == 0) { // No messages in the source folder
System.out.println(folder.getName() + " is empty");
// Close folder, store and return
folder.close(false);
store.close();
return;
}
// Open destination folder, create if reqd
Folder dfolder = store.getFolder(dest);
if (!dfolder.exists())
dfolder.create(Folder.HOLDS_MESSAGES);
if (end == -1)
end = count;
// Get the message objects to copy
Message[] msgs = folder.getMessages(start, end);
System.out.println("Moving " + msgs.length + " messages");
if (msgs.length != 0) {
folder.copyMessages(msgs, dfolder);
folder.setFlags(msgs, new Flags(Flags.Flag.DELETED), true);
// Dump out the Flags of the moved messages, to insure that
// all got deleted
for (int i = 0; i < msgs.length; i++) {
if (!msgs[i].isSet(Flags.Flag.DELETED))
System.out.println("Message # " + msgs[i] +
" not deleted");
}
}
// Close folders and store
folder.close(expunge);
store.close();
} catch (MessagingException mex) {
Exception ex = mex;
do {
System.out.println(ex.getMessage());
if (ex instanceof MessagingException)
ex = ((MessagingException)ex).getNextException();
else
ex = null;
} while (ex != null);
}
}
}

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 1996-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
/**
* msgmultisendsample creates a simple multipart/mixed message and sends it.
* Both body parts are text/plain.
* <p>
* usage: <code>java msgmultisendsample <i>to from smtp true|false</i></code>
* where <i>to</i> and <i>from</i> are the destination and
* origin email addresses, respectively, and <i>smtp</i>
* is the hostname of the machine that has smtp server
* running. The last parameter either turns on or turns off
* debugging during sending.
*
* @author Max Spivak
*/
public class msgmultisendsample {
static String msgText1 = "This is a message body.\nHere's line two.";
static String msgText2 = "This is the text in the message attachment.";
public static void main(String[] args) {
if (args.length != 4) {
System.out.println("usage: java msgmultisend <to> <from> <smtp> true|false");
return;
}
String to = args[0];
String from = args[1];
String host = args[2];
boolean debug = Boolean.valueOf(args[3]).booleanValue();
// create some properties and get the default Session
Properties props = new Properties();
props.put("mail.smtp.host", host);
Session session = Session.getInstance(props, null);
session.setDebug(debug);
try {
// create a message
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = {new InternetAddress(to)};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("JavaMail APIs Multipart Test");
msg.setSentDate(new Date());
// create and fill the first message part
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(msgText1);
// create and fill the second message part
MimeBodyPart mbp2 = new MimeBodyPart();
// Use setText(text, charset), to show it off !
mbp2.setText(msgText2, "us-ascii");
// create the Multipart and its parts to it
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
mp.addBodyPart(mbp2);
// add the Multipart to the message
msg.setContent(mp);
// send the message
Transport.send(msg);
} catch (MessagingException mex) {
mex.printStackTrace();
Exception ex = null;
if ((ex = mex.getNextException()) != null) {
ex.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,248 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import java.util.Properties;
import java.util.Date;
import javax.mail.*;
import javax.mail.internet.*;
/**
* Demo app that shows how to construct and send an RFC822
* (singlepart) message.
*
* XXX - allow more than one recipient on the command line
*
* @author Max Spivak
* @author Bill Shannon
*/
public class msgsend {
public static void main(String[] argv) {
String to, subject = null, from = null,
cc = null, bcc = null, url = null;
String mailhost = null;
String mailer = "msgsend";
String file = null;
String protocol = null, host = null, user = null, password = null;
String record = null; // name of folder in which to record mail
boolean debug = false;
BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
int optind;
/*
* Process command line arguments.
*/
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-M")) {
mailhost = argv[++optind];
} else if (argv[optind].equals("-f")) {
record = argv[++optind];
} else if (argv[optind].equals("-a")) {
file = argv[++optind];
} else if (argv[optind].equals("-s")) {
subject = argv[++optind];
} else if (argv[optind].equals("-o")) { // originator
from = argv[++optind];
} else if (argv[optind].equals("-c")) {
cc = argv[++optind];
} else if (argv[optind].equals("-b")) {
bcc = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-d")) {
debug = true;
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: msgsend [[-L store-url] | [-T prot] [-H host] [-U user] [-P passwd]]");
System.out.println(
"\t[-s subject] [-o from-address] [-c cc-addresses] [-b bcc-addresses]");
System.out.println(
"\t[-f record-mailbox] [-M transport-host] [-a attach-file] [-d] [address]");
System.exit(1);
} else {
break;
}
}
try {
/*
* Prompt for To and Subject, if not specified.
*/
if (optind < argv.length) {
// XXX - concatenate all remaining arguments
to = argv[optind];
System.out.println("To: " + to);
} else {
System.out.print("To: ");
System.out.flush();
to = in.readLine();
}
if (subject == null) {
System.out.print("Subject: ");
System.out.flush();
subject = in.readLine();
} else {
System.out.println("Subject: " + subject);
}
/*
* Initialize the JavaMail Session.
*/
Properties props = System.getProperties();
// XXX - could use Session.getTransport() and Transport.connect()
// XXX - assume we're using SMTP
if (mailhost != null)
props.put("mail.smtp.host", mailhost);
// Get a Session object
Session session = Session.getInstance(props, null);
if (debug)
session.setDebug(true);
/*
* Construct the message and send it.
*/
Message msg = new MimeMessage(session);
if (from != null)
msg.setFrom(new InternetAddress(from));
else
msg.setFrom();
msg.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to, false));
if (cc != null)
msg.setRecipients(Message.RecipientType.CC,
InternetAddress.parse(cc, false));
if (bcc != null)
msg.setRecipients(Message.RecipientType.BCC,
InternetAddress.parse(bcc, false));
msg.setSubject(subject);
String text = collect(in);
if (file != null) {
// Attach the specified file.
// We need a multipart message to hold the attachment.
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(text);
MimeBodyPart mbp2 = new MimeBodyPart();
mbp2.attachFile(file);
MimeMultipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
mp.addBodyPart(mbp2);
msg.setContent(mp);
} else {
// If the desired charset is known, you can use
// setText(text, charset)
msg.setText(text);
}
msg.setHeader("X-Mailer", mailer);
msg.setSentDate(new Date());
// send the thing off
Transport.send(msg);
System.out.println("\nMail was sent successfully.");
/*
* Save a copy of the message, if requested.
*/
if (record != null) {
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, user, password);
else
store.connect();
}
// Get record Folder. Create if it does not exist.
Folder folder = store.getFolder(record);
if (folder == null) {
System.err.println("Can't get record folder.");
System.exit(1);
}
if (!folder.exists())
folder.create(Folder.HOLDS_MESSAGES);
Message[] msgs = new Message[1];
msgs[0] = msg;
folder.appendMessages(msgs);
System.out.println("Mail was recorded successfully.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Read the body of the message until EOF.
*/
public static String collect(BufferedReader in) throws IOException {
String line;
StringBuffer sb = new StringBuffer();
while ((line = in.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
return sb.toString();
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 1996-2011 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
/**
* msgsendsample creates a very simple text/plain message and sends it.
* <p>
* usage: <code>java msgsendsample <i>to from smtphost true|false</i></code>
* where <i>to</i> and <i>from</i> are the destination and
* origin email addresses, respectively, and <i>smtphost</i>
* is the hostname of the machine that has the smtp server
* running. The last parameter either turns on or turns off
* debugging during sending.
*
* @author Max Spivak
*/
public class msgsendsample {
static String msgText = "This is a message body.\nHere's the second line.";
public static void main(String[] args) {
if (args.length != 4) {
usage();
System.exit(1);
}
System.out.println();
String to = args[0];
String from = args[1];
String host = args[2];
boolean debug = Boolean.valueOf(args[3]).booleanValue();
// create some properties and get the default Session
Properties props = new Properties();
props.put("mail.smtp.host", host);
if (debug) props.put("mail.debug", args[3]);
Session session = Session.getInstance(props, null);
session.setDebug(debug);
try {
// create a message
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = {new InternetAddress(to)};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("JavaMail APIs Test");
msg.setSentDate(new Date());
// If the desired charset is known, you can use
// setText(text, charset)
msg.setText(msgText);
Transport.send(msg);
} catch (MessagingException mex) {
System.out.println("\n--Exception handling in msgsendsample.java");
mex.printStackTrace();
System.out.println();
Exception ex = mex;
do {
if (ex instanceof SendFailedException) {
SendFailedException sfex = (SendFailedException)ex;
Address[] invalid = sfex.getInvalidAddresses();
if (invalid != null) {
System.out.println(" ** Invalid Addresses");
for (int i = 0; i < invalid.length; i++)
System.out.println(" " + invalid[i]);
}
Address[] validUnsent = sfex.getValidUnsentAddresses();
if (validUnsent != null) {
System.out.println(" ** ValidUnsent Addresses");
for (int i = 0; i < validUnsent.length; i++)
System.out.println(" "+validUnsent[i]);
}
Address[] validSent = sfex.getValidSentAddresses();
if (validSent != null) {
System.out.println(" ** ValidSent Addresses");
for (int i = 0; i < validSent.length; i++)
System.out.println(" "+validSent[i]);
}
}
System.out.println();
if (ex instanceof MessagingException)
ex = ((MessagingException)ex).getNextException();
else
ex = null;
} while (ex != null);
}
}
private static void usage() {
System.out.println("usage: java msgsendsample <to> <from> <smtp> true|false");
}
}

View File

@ -0,0 +1,445 @@
/*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.event.*;
import javax.mail.internet.*;
/*
* Demo app that exercises the Message interfaces.
* Show information about and contents of messages.
*
* @author John Mani
* @author Bill Shannon
*/
public class msgshow {
static String protocol;
static String host = null;
static String user = null;
static String password = null;
static String mbox = null;
static String url = null;
static int port = -1;
static boolean verbose = false;
static boolean debug = false;
static boolean showStructure = false;
static boolean showMessage = false;
static boolean showAlert = false;
static boolean saveAttachments = false;
static int attnum = 1;
public static void main(String argv[]) {
int optind;
InputStream msgStream = System.in;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-v")) {
verbose = true;
} else if (argv[optind].equals("-D")) {
debug = true;
} else if (argv[optind].equals("-f")) {
mbox = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-p")) {
port = Integer.parseInt(argv[++optind]);
} else if (argv[optind].equals("-s")) {
showStructure = true;
} else if (argv[optind].equals("-S")) {
saveAttachments = true;
} else if (argv[optind].equals("-m")) {
showMessage = true;
} else if (argv[optind].equals("-a")) {
showAlert = true;
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: msgshow [-L url] [-T protocol] [-H host] [-p port] [-U user]");
System.out.println(
"\t[-P password] [-f mailbox] [msgnum ...] [-v] [-D] [-s] [-S] [-a]");
System.out.println(
"or msgshow -m [-v] [-D] [-s] [-S] [-f msg-file]");
System.exit(1);
} else {
break;
}
}
try {
// Get a Properties object
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getInstance(props, null);
session.setDebug(debug);
if (showMessage) {
MimeMessage msg;
if (mbox != null)
msg = new MimeMessage(session,
new BufferedInputStream(new FileInputStream(mbox)));
else
msg = new MimeMessage(session, msgStream);
dumpPart(msg);
System.exit(0);
}
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
if (showAlert) {
store.addStoreListener(new StoreListener() {
public void notification(StoreEvent e) {
String s;
if (e.getMessageType() == StoreEvent.ALERT)
s = "ALERT: ";
else
s = "NOTICE: ";
System.out.println(s + e.getMessage());
}
});
}
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, port, user, password);
else
store.connect();
}
// Open the Folder
Folder folder = store.getDefaultFolder();
if (folder == null) {
System.out.println("No default folder");
System.exit(1);
}
if (mbox == null)
mbox = "INBOX";
folder = folder.getFolder(mbox);
if (folder == null) {
System.out.println("Invalid folder");
System.exit(1);
}
// try to open read/write and if that fails try read-only
try {
folder.open(Folder.READ_WRITE);
} catch (MessagingException ex) {
folder.open(Folder.READ_ONLY);
}
int totalMessages = folder.getMessageCount();
if (totalMessages == 0) {
System.out.println("Empty folder");
folder.close(false);
store.close();
System.exit(1);
}
if (verbose) {
int newMessages = folder.getNewMessageCount();
System.out.println("Total messages = " + totalMessages);
System.out.println("New messages = " + newMessages);
System.out.println("-------------------------------");
}
if (optind >= argv.length) {
// Attributes & Flags for all messages ..
Message[] msgs = folder.getMessages();
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.FLAGS);
fp.add("X-Mailer");
folder.fetch(msgs, fp);
for (int i = 0; i < msgs.length; i++) {
System.out.println("--------------------------");
System.out.println("MESSAGE #" + (i + 1) + ":");
dumpEnvelope(msgs[i]);
// dumpPart(msgs[i]);
}
} else {
while (optind < argv.length) {
int msgnum = Integer.parseInt(argv[optind++]);
System.out.println("Getting message number: " + msgnum);
Message m = null;
try {
m = folder.getMessage(msgnum);
dumpPart(m);
} catch (IndexOutOfBoundsException iex) {
System.out.println("Message number out of range");
}
}
}
folder.close(false);
store.close();
} catch (Exception ex) {
System.out.println("Oops, got exception! " + ex.getMessage());
ex.printStackTrace();
System.exit(1);
}
System.exit(0);
}
public static void dumpPart(Part p) throws Exception {
if (p instanceof Message)
dumpEnvelope((Message)p);
/** Dump input stream ..
InputStream is = p.getInputStream();
// If "is" is not already buffered, wrap a BufferedInputStream
// around it.
if (!(is instanceof BufferedInputStream))
is = new BufferedInputStream(is);
int c;
while ((c = is.read()) != -1)
System.out.write(c);
**/
String ct = p.getContentType();
try {
pr("CONTENT-TYPE: " + (new ContentType(ct)).toString());
} catch (ParseException pex) {
pr("BAD CONTENT-TYPE: " + ct);
}
String filename = p.getFileName();
if (filename != null)
pr("FILENAME: " + filename);
/*
* Using isMimeType to determine the content type avoids
* fetching the actual content data until we need it.
*/
if (p.isMimeType("text/plain")) {
pr("This is plain text");
pr("---------------------------");
if (!showStructure && !saveAttachments)
System.out.println((String)p.getContent());
} else if (p.isMimeType("multipart/*")) {
pr("This is a Multipart");
pr("---------------------------");
Multipart mp = (Multipart)p.getContent();
level++;
int count = mp.getCount();
for (int i = 0; i < count; i++)
dumpPart(mp.getBodyPart(i));
level--;
} else if (p.isMimeType("message/rfc822")) {
pr("This is a Nested Message");
pr("---------------------------");
level++;
dumpPart((Part)p.getContent());
level--;
} else {
if (!showStructure && !saveAttachments) {
/*
* If we actually want to see the data, and it's not a
* MIME type we know, fetch it and check its Java type.
*/
Object o = p.getContent();
if (o instanceof String) {
pr("This is a string");
pr("---------------------------");
System.out.println((String)o);
} else if (o instanceof InputStream) {
pr("This is just an input stream");
pr("---------------------------");
InputStream is = (InputStream)o;
int c;
while ((c = is.read()) != -1)
System.out.write(c);
} else {
pr("This is an unknown type");
pr("---------------------------");
pr(o.toString());
}
} else {
// just a separator
pr("---------------------------");
}
}
/*
* If we're saving attachments, write out anything that
* looks like an attachment into an appropriately named
* file. Don't overwrite existing files to prevent
* mistakes.
*/
if (saveAttachments && level != 0 && p instanceof MimeBodyPart &&
!p.isMimeType("multipart/*")) {
String disp = p.getDisposition();
// many mailers don't include a Content-Disposition
if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT)) {
if (filename == null)
filename = "Attachment" + attnum++;
pr("Saving attachment to file " + filename);
try {
File f = new File(filename);
if (f.exists())
// XXX - could try a series of names
throw new IOException("file exists");
((MimeBodyPart)p).saveFile(f);
} catch (IOException ex) {
pr("Failed to save attachment: " + ex);
}
pr("---------------------------");
}
}
}
public static void dumpEnvelope(Message m) throws Exception {
pr("This is the message envelope");
pr("---------------------------");
Address[] a;
// FROM
if ((a = m.getFrom()) != null) {
for (int j = 0; j < a.length; j++)
pr("FROM: " + a[j].toString());
}
// REPLY TO
if ((a = m.getReplyTo()) != null) {
for (int j = 0; j < a.length; j++)
pr("REPLY TO: " + a[j].toString());
}
// TO
if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
for (int j = 0; j < a.length; j++) {
pr("TO: " + a[j].toString());
InternetAddress ia = (InternetAddress)a[j];
if (ia.isGroup()) {
InternetAddress[] aa = ia.getGroup(false);
for (int k = 0; k < aa.length; k++)
pr(" GROUP: " + aa[k].toString());
}
}
}
// SUBJECT
pr("SUBJECT: " + m.getSubject());
// DATE
Date d = m.getSentDate();
pr("SendDate: " +
(d != null ? d.toString() : "UNKNOWN"));
// FLAGS
Flags flags = m.getFlags();
StringBuffer sb = new StringBuffer();
Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags
boolean first = true;
for (int i = 0; i < sf.length; i++) {
String s;
Flags.Flag f = sf[i];
if (f == Flags.Flag.ANSWERED)
s = "\\Answered";
else if (f == Flags.Flag.DELETED)
s = "\\Deleted";
else if (f == Flags.Flag.DRAFT)
s = "\\Draft";
else if (f == Flags.Flag.FLAGGED)
s = "\\Flagged";
else if (f == Flags.Flag.RECENT)
s = "\\Recent";
else if (f == Flags.Flag.SEEN)
s = "\\Seen";
else
continue; // skip it
if (first)
first = false;
else
sb.append(' ');
sb.append(s);
}
String[] uf = flags.getUserFlags(); // get the user flag strings
for (int i = 0; i < uf.length; i++) {
if (first)
first = false;
else
sb.append(' ');
sb.append(uf[i]);
}
pr("FLAGS: " + sb.toString());
// X-MAILER
String[] hdrs = m.getHeader("X-Mailer");
if (hdrs != null)
pr("X-Mailer: " + hdrs[0]);
else
pr("X-Mailer NOT available");
}
static String indentStr = " ";
static int level = 0;
/**
* Print a, possibly indented, string.
*/
public static void pr(String s) {
if (showStructure)
System.out.print(indentStr.substring(0, level * 2));
System.out.println(s);
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
/*
* Demo app that exercises the namespace interfaces.
* Show the namespaces supported by a store.
*
* @author Bill Shannon
*/
public class namespace {
static String protocol;
static String host = null;
static String user = null;
static String password = null;
static String url = null;
static int port = -1;
static boolean debug = false;
static String suser = "other";
public static void main(String argv[]) {
int msgnum = -1;
int optind;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-D")) {
debug = true;
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-p")) {
port = Integer.parseInt(argv[++optind]);
} else if (argv[optind].equals("-u")) {
suser = argv[++optind];
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: namespace [-L url] [-T protocol] [-H host] [-p port] [-U user]");
System.out.println(
"\t[-P password] [-u other-user] [-D]");
System.exit(1);
} else {
break;
}
}
try {
// Get a Properties object
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getInstance(props, null);
session.setDebug(debug);
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, port, user, password);
else
store.connect();
}
printFolders("Personal", store.getPersonalNamespaces());
printFolders("User \"" + suser + "\"",
store.getUserNamespaces(suser));
printFolders("Shared", store.getSharedNamespaces());
store.close();
} catch (Exception ex) {
System.out.println("Oops, got exception! " + ex.getMessage());
ex.printStackTrace();
}
System.exit(0);
}
private static void printFolders(String name, Folder[] folders)
throws MessagingException {
System.out.println(name + " Namespace:");
if (folders == null || folders.length == 0) {
System.out.println(" <none>");
return;
}
for (int i = 0; i < folders.length; i++) {
String fn = folders[i].getFullName();
if (fn.length() == 0)
fn = "<default folder>";
try {
System.out.println(" " + fn +
", delimiter \"" + folders[i].getSeparator() + "\"");
Folder[] fl = folders[i].list();
if (fl.length > 0) {
System.out.println(" Subfolders:");
for (int j = 0; j < fl.length; j++)
System.out.println(" " + fl[j].getFullName());
}
} catch (FolderNotFoundException ex) { }
}
}
}

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* A special MimeBodyPart used with MSMessage.
*
* @author John Mani
* @author Bill Shannon
*/
public class MSBodyPart extends MimeBodyPart {
private int start;
private int end;
private String type = UNKNOWN;
private String disposition;
private String encoding;
private String filename = UNKNOWN;
private static final String UNKNOWN = "UNKNOWN";
public MSBodyPart(byte[] content, int start, int end,
String disposition, String encoding) {
this.content = content;
this.start = start;
this.end = end;
this.disposition = disposition;
this.encoding = encoding;
}
public String getContentType() throws MessagingException {
// try to figure this out from the filename extension
if (type == UNKNOWN)
processBegin();
return type;
}
public String getEncoding() throws MessagingException {
return encoding;
}
public String getDisposition() throws MessagingException {
return disposition;
}
public String getFileName() throws MessagingException {
// get filename from the "begin" line
if (filename == UNKNOWN)
processBegin();
return filename;
}
protected InputStream getContentStream() {
return new ByteArrayInputStream(content, start, end - start);
}
/**
* Process the "begin" line to extract the filename,
* and from it determine the Content-Type.
*/
private void processBegin() {
InputStream in = getContentStream();
try {
BufferedReader r = new BufferedReader(new InputStreamReader(in));
String begin = r.readLine();
// format is "begin 666 filename.txt"
if (begin != null && begin.regionMatches(true, 0, "begin ", 0, 6)) {
int i = begin.indexOf(' ', 6);
if (i > 0) {
filename = begin.substring(i + 1);
FileTypeMap map = FileTypeMap.getDefaultFileTypeMap();
type = map.getContentType(filename);
if (type == null)
type = "application/octet-stream";
}
}
} catch (IOException ex) {
// ignore
} finally {
try {
in.close();
} catch (IOException ex) {
// ignore it
}
if (filename == UNKNOWN)
filename = null;
if (type == UNKNOWN || type == null)
type = "text/plain";
}
}
}

View File

@ -0,0 +1,231 @@
/*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
/**
* This class models a UUEncoded Message sent from MS Outlook etc. <p>
*
* The message structure looks like this :=
* [text body] [uuencoded attachment]*
* <p>
* i.e., an optional text/plain main-body, followed by zero or more
* UUENCODE-ed attachments.
*
* @author John Mani
* @author Bill Shannon
* @see javax.mail.internet.MimeMessage
*/
public class MSMessage extends MimeMessage {
private String type;
/**
* Constructor that converts a MimeMessage object into a MSMessage.
*
* @exception MessagingException if the given MimeMessage
* is not a non-MIME MS message, or if an
* IOException occurs when accessing the given
* MimeMessage object
*/
public MSMessage(Session session, MimeMessage msg)
throws MessagingException {
super(session);
if (!isMSMessage(msg)) // sanity check
throw new MessagingException("Not an MS message");
class FastByteArrayOutputStream extends ByteArrayOutputStream {
ByteArrayInputStream toByteArrayInputStream() {
return new ByteArrayInputStream(buf, 0, count);
}
}
// extract the bytes of the given message
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
FastByteArrayOutputStream bos = new FastByteArrayOutputStream();
try {
msg.writeTo(bos);
} catch (IOException ioex) {
throw new MessagingException("IOException", ioex);
} catch (Exception ex) {
throw new MessagingException("Exception", ex);
}
//parse(new ByteArrayInputStream(bos.toByteArray()));
parse(bos.toByteArrayInputStream());
}
/**
* Constructor to create a MSMessage from the given InputStream.
*/
public MSMessage(Session session, InputStream is)
throws MessagingException {
super(session); // setup headerstore etc
parse(is);
}
// parse input stream
protected void parse(InputStream is) throws MessagingException {
// Create a buffered input stream for efficiency
if (!(is instanceof ByteArrayInputStream) &&
!(is instanceof BufferedInputStream))
is = new BufferedInputStream(is);
// Load headerstore
headers.load(is);
/*
* Load the content into a byte[].
* This byte[] is shared among the bodyparts.
*/
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int b;
// XXX - room for performance improvement
while ((b = is.read()) != -1)
bos.write(b);
content = bos.toByteArray();
} catch (IOException ioex) {
throw new MessagingException("IOException", ioex);
}
/*
* Check whether this is multipart.
*/
boolean isMulti = false;
// check for presence of X-MS-Attachment header
String[] att = getHeader("X-MS-Attachment");
if (att != null && att.length > 0)
isMulti = true;
else {
/*
* Fall back to scanning the content.
* We scan the content until we find a sequence that looks
* like the start of a uuencoded block, i.e., "<newline>begin".
* If found, we claim that this is a multipart message.
*/
for (int i = 0; i < content.length; i++) {
int b = content[i] & 0xff; // mask higher byte
if (b == '\r' || b == '\n') {
// start of a new line
if ((i + 5) < content.length) {
// can there be a "begin" now?
String s = toString(content, i+1, i+6);
if (s.equalsIgnoreCase("begin")) {
isMulti= true;
break;
}
}
}
}
}
if (isMulti) {
type = "multipart/mixed";
dh = new DataHandler(new MSMultipartDataSource(this, content));
} else {
type = "text/plain"; // charset = ?
dh = new DataHandler(new MimePartDataSource(this));
}
modified = false;
}
/**
* Return content-type
*/
public String getContentType() throws MessagingException {
return type;
}
/**
* Return content-disposition
*/
public String getDisposition() throws MessagingException {
return "inline";
}
/**
* Return content-transfer-encoding
*/
public String getEncoding() throws MessagingException {
return "7bit";
}
/**
* Check whether the given MimeMessage object represents a
* non-MIME message sent by Outlook. Such a message will
* have no MIME-Version header, may have an X-Mailer header
* that includes the word "Microsoft", and will have at least
* one X-MS-Attachment header.
*/
public static boolean isMSMessage(MimeMessage msg)
throws MessagingException {
// Check whether the MIME header is present
if (msg.getHeader("MIME-Version") != null)
// MIME-Version header present, should be a MIME message
return false;
/*
* XXX - disabled X-Mailer check because many sample messages
* I saw didn't have an X-Mailer header at all.
*/
if (false) {
// Check X-Mailer
String mailer = msg.getHeader("X-mailer", null);
if (mailer == null) // No X-mailer ?
return false; // Oh well !
if (mailer.indexOf("Microsoft") == -1) // Not MS stuff ?
return false;
}
// Check X-MS-Attachment header
// XXX - not all such messages have this header
String[] att = msg.getHeader("X-MS-Attachment");
if (att == null || att.length == 0)
return false;
return true;
}
// convert given byte array of ASCII characters to string
static String toString(byte[] b, int start, int end) {
int size = end - start;
char[] theChars = new char[size];
for (int i = 0, j = start; i < size; )
theChars[i++] = (char)b[j++];
return new String(theChars);
}
}

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* A special MultipartDataSource used with MSMessage.
*
* @author John Mani
* @author Bill Shannon
*/
public class MSMultipartDataSource extends MimePartDataSource
implements MultipartDataSource {
//private List<MSBodyPart> parts;
private List parts;
public MSMultipartDataSource(MimePart part, byte[] content)
throws MessagingException {
super(part);
//parts = new ArrayList<MSBodyPart>();
parts = new ArrayList();
/*
* Parse the text of the message to find the attachments.
*
* Currently we just look for the lines that mark the
* begin and end of uuencoded data, but this can be
* fooled by similar text in the message body. Instead,
* we could use the Encoding header, which indicates how
* many lines are in each body part. For example:
*
* Encoding: 41 TEXT, 38 UUENCODE, 3155 UUENCODE, 1096 UUENCODE
*
* Similarly, we could get the filenames of the attachments
* from the X-MS-Attachment headers. For example:
*
* X-MS-Attachment: ATT00000.htx 0 00-00-1980 00:00
* X-MS-Attachment: Serengeti 2GG.mpp 0 00-00-1980 00:00
* X-MS-Attachment: project team update 031298.doc 0 00-00-1980 00:00
*
* (Note that there might be unquoted spaces in the filename.)
*/
int pos = startsWith(content, 0, "begin");
if (pos == -1)
throw new MessagingException("invalid multipart");
if (pos > 0) // we have an unencoded main body part
parts.add(new MSBodyPart(content, 0, pos, "inline", "7bit"));
else // no main body part
pos = 0;
// now collect all the uuencoded individual body parts
int start;
for (;;) {
start = startsWith(content, pos, "begin");
if (start == -1)
break;
pos = startsWith(content, start, "end");
if (pos == -1)
break;
pos += 3; // skip to the end of "end"
parts.add(new MSBodyPart(content, start, pos,
"attachment", "uuencode"));
}
}
public int getCount() {
return parts.size();
}
public BodyPart getBodyPart(int index) throws MessagingException {
return (BodyPart)parts.get(index);
}
/**
* This method scans the given byte[], beginning at "start", for
* lines that begin with the sequence "seq". If found, the start
* position of the sequence within the byte[] is returned.
*/
private int startsWith(byte[] content, int start, String seq) {
int slen = seq.length();
boolean bol = true;
for (int i = start; i < content.length; i++) {
if (bol) {
if ((i + slen) < content.length) {
String s = MSMessage.toString(content, i, i + slen);
if (s.equalsIgnoreCase(seq))
return i;
}
}
int b = content[i] & 0xff;
bol = b == '\r' || b == '\n';
}
return -1;
}
}

View File

@ -0,0 +1,9 @@
The classes in this directory allow processing old style non-MIME
messages created by Microsoft Outlook. Use them like this:
if (MSMessage.isMSMessage(msg))
msg = new MSMessage(session, msg);
Note that these classes are not particularly efficient or optimized,
but they show how to process these non-MIME messages and make them
look like MIME messages.

View File

@ -0,0 +1,252 @@
/*
* Copyright (c) 1997-2016 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.mail.*;
import javax.mail.internet.*;
/*
* Copy folder hierarchies between different Stores. This is a useful
* utility to populate new (and possibly empty) mail stores. Specify
* both the source and destination folders as URLs.
*
* @author John Mani
* @author Bill Shannon
*/
public class populate {
static boolean force = false;
static boolean skipSpecial = false;
static boolean clear = false;
static boolean dontPreserveFlags = false;
static boolean warn = false;
public static void main(String argv[]) {
String srcURL = null;
String dstURL = null;
boolean debug = false;
int optind;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-s")) {
srcURL = argv[++optind];
} else if (argv[optind].equals("-d")) {
dstURL = argv[++optind];
} else if (argv[optind].equals("-D")) {
debug = true;
} else if (argv[optind].equals("-f")) {
force = true;
} else if (argv[optind].equals("-S")) {
skipSpecial = true;
} else if (argv[optind].equals("-c")) {
clear = true;
} else if (argv[optind].equals("-P")) {
dontPreserveFlags = true;
} else if (argv[optind].equals("-W")) {
warn = true;
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
printUsage();
System.exit(1);
} else {
break;
}
}
try {
if (srcURL == null || dstURL == null) {
printUsage();
System.exit(1);
}
Session session = Session.getInstance(
System.getProperties(), null);
session.setDebug(debug);
// Get source folder
URLName srcURLName = new URLName(srcURL);
Folder srcFolder;
// Check if the source URL has a folder specified. If
// not, we use the default folder
if (srcURLName.getFile() == null) {
Store s = session.getStore(srcURLName);
s.connect();
srcFolder = s.getDefaultFolder();
} else {
srcFolder = session.getFolder(new URLName(srcURL));
if (!srcFolder.exists()) {
System.out.println("source folder does not exist");
srcFolder.getStore().close();
System.exit(1);
}
}
// Set up destination folder
URLName dstURLName = new URLName(dstURL);
Folder dstFolder;
// Check if the destination URL has a folder specified. If
// not, we use the source folder name
if (dstURLName.getFile() == null) {
Store s = session.getStore(dstURLName);
s.connect();
dstFolder = s.getFolder(srcFolder.getName());
} else
dstFolder = session.getFolder(dstURLName);
if (clear && dstFolder.exists()) {
if (!dstFolder.delete(true)) {
System.out.println("couldn't delete " +
dstFolder.getFullName());
return;
}
}
copy(srcFolder, dstFolder);
// Close the respective stores.
srcFolder.getStore().close();
dstFolder.getStore().close();
} catch (MessagingException mex) {
System.out.println(mex.getMessage());
mex.printStackTrace();
}
}
private static void copy(Folder src, Folder dst)
throws MessagingException {
System.out.println("Populating " + dst.getFullName());
Folder ddst = dst;
Folder[] srcFolders = null;
if ((src.getType() & Folder.HOLDS_FOLDERS) != 0)
srcFolders = src.list();
boolean srcHasChildren = srcFolders != null && srcFolders.length > 0;
if (!dst.exists()) {
// Create it.
boolean dstHoldsOnlyFolders = false;
if (!dst.create(src.getType())) {
// might not be able to create a folder that holds both
if (!dst.create(srcHasChildren ? Folder.HOLDS_FOLDERS :
Folder.HOLDS_MESSAGES)) {
// might only be able to create one type (Gmail)
if (!dst.create(Folder.HOLDS_MESSAGES)) {
System.out.println("couldn't create " +
dst.getFullName());
return;
}
}
dstHoldsOnlyFolders = srcHasChildren;
}
// Copy over any messges from src to dst
if ((src.getType() & Folder.HOLDS_MESSAGES) != 0) {
src.open(Folder.READ_ONLY);
if (dstHoldsOnlyFolders) {
if (src.getMessageCount() > 0) {
System.out.println("Unable to copy messages from " +
src.getFullName() + " to " + dst.getFullName() +
" because destination holds only folders");
}
} else
copyMessages(src, dst);
src.close(false);
}
} else {
System.out.println(dst.getFullName() + " already exists");
// Copy over any messges from src to dst
if (force && (src.getType() & Folder.HOLDS_MESSAGES) != 0) {
src.open(Folder.READ_ONLY);
copyMessages(src, dst);
src.close(false);
}
}
// Copy over subfolders
if (srcHasChildren) {
for (int i = 0; i < srcFolders.length; i++) {
// skip special directories?
if (skipSpecial) {
if (srcFolders[i].getName().equals("SCCS") ||
srcFolders[i].getName().equals("Drafts") ||
srcFolders[i].getName().equals("Trash") ||
srcFolders[i].getName().equals("Shared Folders"))
continue;
}
copy(srcFolders[i], dst.getFolder(srcFolders[i].getName()));
}
}
}
/**
* Copy message from src to dst. If dontPreserveFlags is set
* we first copy the messages to memory, clear all the flags,
* and then copy to the destination.
*/
private static void copyMessages(Folder src, Folder dst)
throws MessagingException {
Message[] msgs = src.getMessages();
if (dontPreserveFlags) {
for (int i = 0; i < msgs.length; i++) {
MimeMessage m = new MimeMessage((MimeMessage)msgs[i]);
m.setFlags(m.getFlags(), false);
msgs[i] = m;
}
}
if (warn) {
// have to copy messages one at a time
for (int i = 0; i < msgs.length; i++) {
try {
src.copyMessages(new Message[] { msgs[i] }, dst);
} catch (MessagingException mex) {
System.out.println("WARNING: Copy of message " + (i + 1) +
" from " + src.getFullName() +
" to " + dst.getFullName() +
" failed: " + mex.toString());
}
}
} else
src.copyMessages(msgs, dst);
}
private static void printUsage() {
System.out.println("populate [-D] [-f] [-S] [-c] " +
"-s source_url -d dest_url");
System.out.println("URLs are of the form: " +
"protocol://username:password@hostname/foldername");
System.out.println("The destination URL does not need a foldername," +
" in which case, the source foldername is used");
}
}

View File

@ -0,0 +1,172 @@
/*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* This class demonstrates how to query the registry for available
* Providers, set default providers, etc. See section 5.2 in the
* JavaMail Spec for details on how to use the registry.
*
* See the comments inline for what's happening.
*
* @author Max Spivak
*/
public class registry {
// let's remember a few providers
static Provider _aProvider, _bProvider, _sunSMTP, _sunIMAP;
public static void main(String[] args) {
Properties props = new Properties();
// set smtp and imap to be our default
// transport and store protocols, respectively
props.put("mail.transport.protocol", "smtp");
props.put("mail.store.protocol", "imap");
//
props.put("mail.smtp.class", "com.sun.mail.smtp.SMTPTransport");
props.put("mail.imap.class", "com.sun.mail.imap.IMAPStore");
Session session = Session.getInstance(props, null);
//session.setDebug(true);
// Retrieve all configured providers from the Session
System.out.println("\n------ getProviders()----------");
Provider[] providers = session.getProviders();
for (int i = 0; i < providers.length; i++) {
System.out.println("** " + providers[i]);
// let's remember some providers so that we can use them later
// (I'm explicitly showing multiple ways of testing Providers)
// BTW, no Provider "ACME Corp" will be found in the default
// setup b/c its not in any javamail.providers resource files
String s = null;
if (((s = providers[i].getVendor()) != null) &&
s.startsWith("ACME Corp")) {
_aProvider = providers[i];
}
// this Provider won't be found by default either
if (providers[i].getClassName().endsWith("application.smtp"))
_bProvider = providers[i];
// this Provider will be found since com.sun.mail.imap.IMAPStore
// is configured in javamail.default.providers
if (providers[i].getClassName().equals("com.sun.mail.imap.IMAPStore")){
_sunIMAP = providers[i];
}
// this Provider will be found as well since there is an
// Oracle SMTP transport configured by
// default in javamail.default.providers
if (((s = providers[i].getVendor()) != null) &&
s.startsWith("Oracle") &&
providers[i].getType() == Provider.Type.TRANSPORT &&
providers[i].getProtocol().equalsIgnoreCase("smtp")) {
_sunSMTP = providers[i];
}
}
System.out.println("\n------ initial protocol defaults -------");
try {
System.out.println("imap: " + session.getProvider("imap"));
System.out.println("smtp: " + session.getProvider("smtp"));
// the NNTP provider will fail since we don't have one configured
System.out.println("nntp: " + session.getProvider("nntp"));
} catch (NoSuchProviderException mex) {
System.out.println(">> This exception is OK since there is no NNTP Provider configured by default");
mex.printStackTrace();
}
System.out.println("\n------ set new protocol defaults ------");
// set some new defaults
try {
// since _aProvider isn't configured, this will fail
session.setProvider(_aProvider); // will fail
} catch (NoSuchProviderException mex) {
System.out.println(">> Exception expected: _aProvider is null");
mex.printStackTrace();
}
try {
// _sunIMAP provider should've configured correctly; should work
session.setProvider(_sunIMAP);
} catch (NoSuchProviderException mex) { mex.printStackTrace(); }
try {
System.out.println("imap: " + session.getProvider("imap"));
System.out.println("smtp: " + session.getProvider("smtp"));
} catch (NoSuchProviderException mex) { mex.printStackTrace(); }
System.out.println("\n\n----- get some stores ---------");
// multiple ways to retrieve stores. these will print out the
// string "imap:" since its the URLName for the store
try {
System.out.println("getStore(): " + session.getStore());
System.out.println("getStore(Provider): " +
session.getStore(_sunIMAP));
} catch (NoSuchProviderException mex) {
mex.printStackTrace();
}
try {
System.out.println("getStore(imap): " + session.getStore("imap"));
// pop3 will fail since it doesn't exist
System.out.println("getStore(pop3): " + session.getStore("pop3"));
} catch (NoSuchProviderException mex) {
System.out.println(">> Exception expected: no pop3 provider");
mex.printStackTrace();
}
System.out.println("\n\n----- now for transports/addresses ---------");
// retrieve transports; these will print out "smtp:" (like stores did)
try {
System.out.println("getTransport(): " + session.getTransport());
System.out.println("getTransport(Provider): " +
session.getTransport(_sunSMTP));
System.out.println("getTransport(smtp): " +
session.getTransport("smtp"));
System.out.println("getTransport(Address): " +
session.getTransport(new InternetAddress("mspivak@apilon")));
// News will fail since there's no news provider configured
System.out.println("getTransport(News): " +
session.getTransport(new NewsAddress("rec.humor")));
} catch (MessagingException mex) {
System.out.println(">> Exception expected: no news provider configured");
mex.printStackTrace();
}
}
}

View File

@ -0,0 +1,322 @@
/*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;
import javax.activation.*;
/*
* Search the given folder for messages matching the given
* criteria.
*
* @author John Mani
*/
public class search {
static String protocol = "imap";
static String host = null;
static String user = null;
static String password = null;
static String mbox = "INBOX";
static String url = null;
static boolean debug = false;
public static void main(String argv[]) {
int optind;
String subject = null;
String from = null;
boolean or = false;
boolean today = false;
int size = -1;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-or")) {
or = true;
} else if (argv[optind].equals("-D")) {
debug = true;
} else if (argv[optind].equals("-f")) {
mbox = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-subject")) {
subject = argv[++optind];
} else if (argv[optind].equals("-from")) {
from = argv[++optind];
} else if (argv[optind].equals("-today")) {
today = true;
} else if (argv[optind].equals("-size")) {
size = Integer.parseInt(argv[++optind]);
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: search [-D] [-L url] [-T protocol] [-H host] " +
"[-U user] [-P password] [-f mailbox] " +
"[-subject subject] [-from from] [-or] [-today]");
System.exit(1);
} else {
break;
}
}
try {
if ((subject == null) && (from == null) && !today && size < 0) {
System.out.println(
"Specify either -subject, -from, -today, or -size");
System.exit(1);
}
// Get a Properties object
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getInstance(props, null);
session.setDebug(debug);
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, user, password);
else
store.connect();
}
// Open the Folder
Folder folder = store.getDefaultFolder();
if (folder == null) {
System.out.println("Cant find default namespace");
System.exit(1);
}
folder = folder.getFolder(mbox);
if (folder == null) {
System.out.println("Invalid folder");
System.exit(1);
}
folder.open(Folder.READ_ONLY);
SearchTerm term = null;
if (subject != null)
term = new SubjectTerm(subject);
if (from != null) {
FromStringTerm fromTerm = new FromStringTerm(from);
if (term != null) {
if (or)
term = new OrTerm(term, fromTerm);
else
term = new AndTerm(term, fromTerm);
}
else
term = fromTerm;
}
if (today) {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
c.set(Calendar.AM_PM, Calendar.AM);
ReceivedDateTerm startDateTerm =
new ReceivedDateTerm(ComparisonTerm.GE, c.getTime());
c.add(Calendar.DATE, 1); // next day
ReceivedDateTerm endDateTerm =
new ReceivedDateTerm(ComparisonTerm.LT, c.getTime());
SearchTerm dateTerm = new AndTerm(startDateTerm, endDateTerm);
if (term != null) {
if (or)
term = new OrTerm(term, dateTerm);
else
term = new AndTerm(term, dateTerm);
}
else
term = dateTerm;
}
if (size >= 0) {
SizeTerm sizeTerm = new SizeTerm(ComparisonTerm.GT, size);
if (term != null) {
if (or)
term = new OrTerm(term, sizeTerm);
else
term = new AndTerm(term, sizeTerm);
}
else
term = sizeTerm;
}
Message[] msgs = folder.search(term);
System.out.println("FOUND " + msgs.length + " MESSAGES");
if (msgs.length == 0) // no match
System.exit(1);
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
folder.fetch(msgs, fp);
for (int i = 0; i < msgs.length; i++) {
System.out.println("--------------------------");
System.out.println("MESSAGE #" + (i + 1) + ":");
dumpPart(msgs[i]);
}
folder.close(false);
store.close();
} catch (Exception ex) {
System.out.println("Oops, got exception! " + ex.getMessage());
ex.printStackTrace();
}
System.exit(1);
}
public static void dumpPart(Part p) throws Exception {
if (p instanceof Message) {
Message m = (Message)p;
Address[] a;
// FROM
if ((a = m.getFrom()) != null) {
for (int j = 0; j < a.length; j++)
System.out.println("FROM: " + a[j].toString());
}
// TO
if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
for (int j = 0; j < a.length; j++)
System.out.println("TO: " + a[j].toString());
}
// SUBJECT
System.out.println("SUBJECT: " + m.getSubject());
// DATE
Date d = m.getSentDate();
System.out.println("SendDate: " +
(d != null ? d.toLocaleString() : "UNKNOWN"));
// FLAGS:
Flags flags = m.getFlags();
StringBuffer sb = new StringBuffer();
Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags
boolean first = true;
for (int i = 0; i < sf.length; i++) {
String s;
Flags.Flag f = sf[i];
if (f == Flags.Flag.ANSWERED)
s = "\\Answered";
else if (f == Flags.Flag.DELETED)
s = "\\Deleted";
else if (f == Flags.Flag.DRAFT)
s = "\\Draft";
else if (f == Flags.Flag.FLAGGED)
s = "\\Flagged";
else if (f == Flags.Flag.RECENT)
s = "\\Recent";
else if (f == Flags.Flag.SEEN)
s = "\\Seen";
else
continue; // skip it
if (first)
first = false;
else
sb.append(' ');
sb.append(s);
}
String[] uf = flags.getUserFlags(); // get the user flag strings
for (int i = 0; i < uf.length; i++) {
if (first)
first = false;
else
sb.append(' ');
sb.append(uf[i]);
}
System.out.println("FLAGS = " + sb.toString());
}
System.out.println("CONTENT-TYPE: " + p.getContentType());
/* Dump input stream
InputStream is = ((MimeMessage)m).getInputStream();
int c;
while ((c = is.read()) != -1)
System.out.write(c);
*/
Object o = p.getContent();
if (o instanceof String) {
System.out.println("This is a String");
System.out.println((String)o);
} else if (o instanceof Multipart) {
System.out.println("This is a Multipart");
Multipart mp = (Multipart)o;
int count = mp.getCount();
for (int i = 0; i < count; i++)
dumpPart(mp.getBodyPart(i));
} else if (o instanceof InputStream) {
System.out.println("This is just an input stream");
InputStream is = (InputStream)o;
int c;
while ((c = is.read()) != -1)
System.out.write(c);
}
}
}

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 1996-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
/**
* sendfile will create a multipart message with the second
* block of the message being the given file.<p>
*
* This demonstrates how to use the FileDataSource to send
* a file via mail.<p>
*
* usage: <code>java sendfile <i>to from smtp file true|false</i></code>
* where <i>to</i> and <i>from</i> are the destination and
* origin email addresses, respectively, and <i>smtp</i>
* is the hostname of the machine that has smtp server
* running. <i>file</i> is the file to send. The next parameter
* either turns on or turns off debugging during sending.
*
* @author Christopher Cotton
*/
public class sendfile {
public static void main(String[] args) {
if (args.length != 5) {
System.out.println("usage: java sendfile <to> <from> <smtp> <file> true|false");
System.exit(1);
}
String to = args[0];
String from = args[1];
String host = args[2];
String filename = args[3];
boolean debug = Boolean.valueOf(args[4]).booleanValue();
String msgText1 = "Sending a file.\n";
String subject = "Sending a file";
// create some properties and get the default Session
Properties props = System.getProperties();
props.put("mail.smtp.host", host);
Session session = Session.getInstance(props, null);
session.setDebug(debug);
try {
// create a message
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = {new InternetAddress(to)};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject(subject);
// create and fill the first message part
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(msgText1);
// create the second message part
MimeBodyPart mbp2 = new MimeBodyPart();
// attach the file to the message
mbp2.attachFile(filename);
/*
* Use the following approach instead of the above line if
* you want to control the MIME type of the attached file.
* Normally you should never need to do this.
*
FileDataSource fds = new FileDataSource(filename) {
public String getContentType() {
return "application/octet-stream";
}
};
mbp2.setDataHandler(new DataHandler(fds));
mbp2.setFileName(fds.getName());
*/
// create the Multipart and add its parts to it
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
mp.addBodyPart(mbp2);
// add the Multipart to the message
msg.setContent(mp);
// set the Date: header
msg.setSentDate(new Date());
/*
* If you want to control the Content-Transfer-Encoding
* of the attached file, do the following. Normally you
* should never need to do this.
*
msg.saveChanges();
mbp2.setHeader("Content-Transfer-Encoding", "base64");
*/
// send the message
Transport.send(msg);
} catch (MessagingException mex) {
mex.printStackTrace();
Exception ex = null;
if ((ex = mex.getNextException()) != null) {
ex.printStackTrace();
}
} catch (IOException ioex) {
ioex.printStackTrace();
}
}
}

View File

@ -0,0 +1,237 @@
/*
* Copyright (c) 1998-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import java.util.Properties;
import java.util.Date;
import javax.mail.*;
import javax.activation.*;
import javax.mail.internet.*;
import javax.mail.util.*;
/**
* Demo app that shows how to construct and send a single part html
* message. Note that the same basic technique can be used to send
* data of any type.
*
* @author John Mani
* @author Bill Shannon
* @author Max Spivak
*/
public class sendhtml {
public static void main(String[] argv) {
new sendhtml(argv);
}
public sendhtml(String[] argv) {
String to, subject = null, from = null,
cc = null, bcc = null, url = null;
String mailhost = null;
String mailer = "sendhtml";
String protocol = null, host = null, user = null, password = null;
String record = null; // name of folder in which to record mail
boolean debug = false;
BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
int optind;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-M")) {
mailhost = argv[++optind];
} else if (argv[optind].equals("-f")) {
record = argv[++optind];
} else if (argv[optind].equals("-s")) {
subject = argv[++optind];
} else if (argv[optind].equals("-o")) { // originator
from = argv[++optind];
} else if (argv[optind].equals("-c")) {
cc = argv[++optind];
} else if (argv[optind].equals("-b")) {
bcc = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-d")) {
debug = true;
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: sendhtml [[-L store-url] | [-T prot] [-H host] [-U user] [-P passwd]]");
System.out.println(
"\t[-s subject] [-o from-address] [-c cc-addresses] [-b bcc-addresses]");
System.out.println(
"\t[-f record-mailbox] [-M transport-host] [-d] [address]");
System.exit(1);
} else {
break;
}
}
try {
if (optind < argv.length) {
// XXX - concatenate all remaining arguments
to = argv[optind];
System.out.println("To: " + to);
} else {
System.out.print("To: ");
System.out.flush();
to = in.readLine();
}
if (subject == null) {
System.out.print("Subject: ");
System.out.flush();
subject = in.readLine();
} else {
System.out.println("Subject: " + subject);
}
Properties props = System.getProperties();
// XXX - could use Session.getTransport() and Transport.connect()
// XXX - assume we're using SMTP
if (mailhost != null)
props.put("mail.smtp.host", mailhost);
// Get a Session object
Session session = Session.getInstance(props, null);
if (debug)
session.setDebug(true);
// construct the message
Message msg = new MimeMessage(session);
if (from != null)
msg.setFrom(new InternetAddress(from));
else
msg.setFrom();
msg.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to, false));
if (cc != null)
msg.setRecipients(Message.RecipientType.CC,
InternetAddress.parse(cc, false));
if (bcc != null)
msg.setRecipients(Message.RecipientType.BCC,
InternetAddress.parse(bcc, false));
msg.setSubject(subject);
collect(in, msg);
msg.setHeader("X-Mailer", mailer);
msg.setSentDate(new Date());
// send the thing off
Transport.send(msg);
System.out.println("\nMail was sent successfully.");
// Keep a copy, if requested.
if (record != null) {
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, user, password);
else
store.connect();
}
// Get record Folder. Create if it does not exist.
Folder folder = store.getFolder(record);
if (folder == null) {
System.err.println("Can't get record folder.");
System.exit(1);
}
if (!folder.exists())
folder.create(Folder.HOLDS_MESSAGES);
Message[] msgs = new Message[1];
msgs[0] = msg;
folder.appendMessages(msgs);
System.out.println("Mail was recorded successfully.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void collect(BufferedReader in, Message msg)
throws MessagingException, IOException {
String line;
String subject = msg.getSubject();
StringBuffer sb = new StringBuffer();
sb.append("<HTML>\n");
sb.append("<HEAD>\n");
sb.append("<TITLE>\n");
sb.append(subject + "\n");
sb.append("</TITLE>\n");
sb.append("</HEAD>\n");
sb.append("<BODY>\n");
sb.append("<H1>" + subject + "</H1>" + "\n");
while ((line = in.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
sb.append("</BODY>\n");
sb.append("</HTML>\n");
msg.setDataHandler(new DataHandler(
new ByteArrayDataSource(sb.toString(), "text/html")));
}
}

View File

@ -0,0 +1,371 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import java.net.InetAddress;
import java.util.Properties;
import java.util.Date;
import javax.mail.*;
import javax.mail.internet.*;
import com.sun.mail.smtp.*;
/**
* Demo app that shows how to construct and send an RFC822
* (singlepart) message.
*
* XXX - allow more than one recipient on the command line
*
* This is just a variant of msgsend.java that demonstrates use of
* some SMTP-specific features.
*
* @author Max Spivak
* @author Bill Shannon
*/
public class smtpsend {
/**
* Example of how to extend the SMTPTransport class.
* This example illustrates how to issue the XACT
* command before the SMTPTransport issues the DATA
* command.
*
public static class SMTPExtension extends SMTPTransport {
public SMTPExtension(Session session, URLName url) {
super(session, url);
// to check that we're being used
System.out.println("SMTPExtension: constructed");
}
protected synchronized OutputStream data() throws MessagingException {
if (supportsExtension("XACCOUNTING"))
issueCommand("XACT", 250);
return super.data();
}
}
*/
public static void main(String[] argv) {
String to, subject = null, from = null,
cc = null, bcc = null, url = null;
String mailhost = null;
String mailer = "smtpsend";
String file = null;
String protocol = null, host = null, user = null, password = null;
String record = null; // name of folder in which to record mail
boolean debug = false;
boolean verbose = false;
boolean auth = false;
String prot = "smtp";
BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
int optind;
/*
* Process command line arguments.
*/
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-M")) {
mailhost = argv[++optind];
} else if (argv[optind].equals("-f")) {
record = argv[++optind];
} else if (argv[optind].equals("-a")) {
file = argv[++optind];
} else if (argv[optind].equals("-s")) {
subject = argv[++optind];
} else if (argv[optind].equals("-o")) { // originator
from = argv[++optind];
} else if (argv[optind].equals("-c")) {
cc = argv[++optind];
} else if (argv[optind].equals("-b")) {
bcc = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("-d")) {
debug = true;
} else if (argv[optind].equals("-v")) {
verbose = true;
} else if (argv[optind].equals("-A")) {
auth = true;
} else if (argv[optind].equals("-S")) {
prot = "smtps";
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println(
"Usage: smtpsend [[-L store-url] | [-T prot] [-H host] [-U user] [-P passwd]]");
System.out.println(
"\t[-s subject] [-o from-address] [-c cc-addresses] [-b bcc-addresses]");
System.out.println(
"\t[-f record-mailbox] [-M transport-host] [-d] [-a attach-file]");
System.out.println(
"\t[-v] [-A] [-S] [address]");
System.exit(1);
} else {
break;
}
}
try {
/*
* Prompt for To and Subject, if not specified.
*/
if (optind < argv.length) {
// XXX - concatenate all remaining arguments
to = argv[optind];
System.out.println("To: " + to);
} else {
System.out.print("To: ");
System.out.flush();
to = in.readLine();
}
if (subject == null) {
System.out.print("Subject: ");
System.out.flush();
subject = in.readLine();
} else {
System.out.println("Subject: " + subject);
}
/*
* Initialize the JavaMail Session.
*/
Properties props = System.getProperties();
if (mailhost != null)
props.put("mail." + prot + ".host", mailhost);
if (auth)
props.put("mail." + prot + ".auth", "true");
/*
* Create a Provider representing our extended SMTP transport
* and set the property to use our provider.
*
Provider p = new Provider(Provider.Type.TRANSPORT, prot,
"smtpsend$SMTPExtension", "JavaMail demo", "no version");
props.put("mail." + prot + ".class", "smtpsend$SMTPExtension");
*/
// Get a Session object
Session session = Session.getInstance(props, null);
if (debug)
session.setDebug(true);
/*
* Register our extended SMTP transport.
*
session.addProvider(p);
*/
/*
* Construct the message and send it.
*/
Message msg = new MimeMessage(session);
if (from != null)
msg.setFrom(new InternetAddress(from));
else
msg.setFrom();
msg.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to, false));
if (cc != null)
msg.setRecipients(Message.RecipientType.CC,
InternetAddress.parse(cc, false));
if (bcc != null)
msg.setRecipients(Message.RecipientType.BCC,
InternetAddress.parse(bcc, false));
msg.setSubject(subject);
String text = collect(in);
if (file != null) {
// Attach the specified file.
// We need a multipart message to hold the attachment.
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(text);
MimeBodyPart mbp2 = new MimeBodyPart();
mbp2.attachFile(file);
MimeMultipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
mp.addBodyPart(mbp2);
msg.setContent(mp);
} else {
// If the desired charset is known, you can use
// setText(text, charset)
msg.setText(text);
}
msg.setHeader("X-Mailer", mailer);
msg.setSentDate(new Date());
// send the thing off
/*
* The simple way to send a message is this:
*
Transport.send(msg);
*
* But we're going to use some SMTP-specific features for
* demonstration purposes so we need to manage the Transport
* object explicitly.
*/
SMTPTransport t =
(SMTPTransport)session.getTransport(prot);
try {
if (auth)
t.connect(mailhost, user, password);
else
t.connect();
t.sendMessage(msg, msg.getAllRecipients());
} finally {
if (verbose)
System.out.println("Response: " +
t.getLastServerResponse());
t.close();
}
System.out.println("\nMail was sent successfully.");
/*
* Save a copy of the message, if requested.
*/
if (record != null) {
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, user, password);
else
store.connect();
}
// Get record Folder. Create if it does not exist.
Folder folder = store.getFolder(record);
if (folder == null) {
System.err.println("Can't get record folder.");
System.exit(1);
}
if (!folder.exists())
folder.create(Folder.HOLDS_MESSAGES);
Message[] msgs = new Message[1];
msgs[0] = msg;
folder.appendMessages(msgs);
System.out.println("Mail was recorded successfully.");
}
} catch (Exception e) {
/*
* Handle SMTP-specific exceptions.
*/
if (e instanceof SendFailedException) {
MessagingException sfe = (MessagingException)e;
if (sfe instanceof SMTPSendFailedException) {
SMTPSendFailedException ssfe =
(SMTPSendFailedException)sfe;
System.out.println("SMTP SEND FAILED:");
if (verbose)
System.out.println(ssfe.toString());
System.out.println(" Command: " + ssfe.getCommand());
System.out.println(" RetCode: " + ssfe.getReturnCode());
System.out.println(" Response: " + ssfe.getMessage());
} else {
if (verbose)
System.out.println("Send failed: " + sfe.toString());
}
Exception ne;
while ((ne = sfe.getNextException()) != null &&
ne instanceof MessagingException) {
sfe = (MessagingException)ne;
if (sfe instanceof SMTPAddressFailedException) {
SMTPAddressFailedException ssfe =
(SMTPAddressFailedException)sfe;
System.out.println("ADDRESS FAILED:");
if (verbose)
System.out.println(ssfe.toString());
System.out.println(" Address: " + ssfe.getAddress());
System.out.println(" Command: " + ssfe.getCommand());
System.out.println(" RetCode: " + ssfe.getReturnCode());
System.out.println(" Response: " + ssfe.getMessage());
} else if (sfe instanceof SMTPAddressSucceededException) {
System.out.println("ADDRESS SUCCEEDED:");
SMTPAddressSucceededException ssfe =
(SMTPAddressSucceededException)sfe;
if (verbose)
System.out.println(ssfe.toString());
System.out.println(" Address: " + ssfe.getAddress());
System.out.println(" Command: " + ssfe.getCommand());
System.out.println(" RetCode: " + ssfe.getReturnCode());
System.out.println(" Response: " + ssfe.getMessage());
}
}
} else {
System.out.println("Got Exception: " + e);
if (verbose)
e.printStackTrace();
}
}
}
/**
* Read the body of the message until EOF.
*/
public static String collect(BufferedReader in) throws IOException {
String line;
StringBuffer sb = new StringBuffer();
while ((line = in.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
return sb.toString();
}
}

View File

@ -0,0 +1,233 @@
/*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.event.*;
import javax.activation.*;
/**
* transport is a simple program that creates a message, explicitly
* retrieves a Transport from the session based on the type of the
* address (it's InternetAddress, so SMTP will be used) and sends
* the message.
*
* usage: <code>java transport <i>"toaddr1[, toaddr2]*" from smtphost
* true|false</i></code><br>
* where <i>to</i> and <i>from</i> are the destination and
* origin email addresses, respectively, and <i>smtphost</i>
* is the hostname of the machine that has the smtp server
* running. The <i>to</i> addresses can be either a single email
* address or a comma-separated list of email addresses in
* quotes, i.e. "joe@machine, jane, max@server.com"
* The last parameter either turns on or turns off
* debugging during sending.
*
* @author Max Spivak
*/
public class transport implements ConnectionListener, TransportListener {
static String msgText = "This is a message body.\nHere's the second line.";
static String msgText2 = "\nThis was sent by transport.java demo program.";
public static void main(String[] args) {
Properties props = System.getProperties();
// parse the arguments
InternetAddress[] addrs = null;
InternetAddress from;
boolean debug = false;
if (args.length != 4) {
usage();
return;
} else {
props.put("mail.smtp.host", args[2]);
if (args[3].equals("true")) {
debug = true;
} else if (args[3].equals("false")) {
debug = false;
} else {
usage();
return;
}
// parse the destination addresses
try {
addrs = InternetAddress.parse(args[0], false);
from = new InternetAddress(args[1]);
} catch (AddressException aex) {
System.out.println("Invalid Address");
aex.printStackTrace();
return;
}
}
// create some properties and get a Session
Session session = Session.getInstance(props, null);
session.setDebug(debug);
transport t = new transport();
t.go(session, addrs, from);
}
public transport() {}
public void go(Session session, InternetAddress[] toAddr,
InternetAddress from) {
Transport trans = null;
try {
// create a message
Message msg = new MimeMessage(session);
msg.setFrom(from);
msg.setRecipients(Message.RecipientType.TO, toAddr);
msg.setSubject("JavaMail APIs transport.java Test");
msg.setSentDate(new Date()); // Date: header
msg.setContent(msgText+msgText2, "text/plain");
msg.saveChanges();
// get the smtp transport for the address
trans = session.getTransport(toAddr[0]);
// register ourselves as listener for ConnectionEvents
// and TransportEvents
trans.addConnectionListener(this);
trans.addTransportListener(this);
// connect the transport
trans.connect();
// send the message
trans.sendMessage(msg, toAddr);
// give the EventQueue enough time to fire its events
try {Thread.sleep(5);}catch(InterruptedException e) {}
} catch (MessagingException mex) {
// give the EventQueue enough time to fire its events
try {Thread.sleep(5);}catch(InterruptedException e) {}
System.out.println("Sending failed with exception:");
mex.printStackTrace();
System.out.println();
Exception ex = mex;
do {
if (ex instanceof SendFailedException) {
SendFailedException sfex = (SendFailedException)ex;
Address[] invalid = sfex.getInvalidAddresses();
if (invalid != null) {
System.out.println(" ** Invalid Addresses");
for (int i = 0; i < invalid.length; i++)
System.out.println(" " + invalid[i]);
}
Address[] validUnsent = sfex.getValidUnsentAddresses();
if (validUnsent != null) {
System.out.println(" ** ValidUnsent Addresses");
for (int i = 0; i < validUnsent.length; i++)
System.out.println(" "+validUnsent[i]);
}
Address[] validSent = sfex.getValidSentAddresses();
if (validSent != null) {
System.out.println(" ** ValidSent Addresses");
for (int i = 0; i < validSent.length; i++)
System.out.println(" "+validSent[i]);
}
}
System.out.println();
if (ex instanceof MessagingException)
ex = ((MessagingException)ex).getNextException();
else
ex = null;
} while (ex != null);
} finally {
try {
// close the transport
if (trans != null)
trans.close();
} catch (MessagingException mex) { /* ignore */ }
}
}
// implement ConnectionListener interface
public void opened(ConnectionEvent e) {
System.out.println(">>> ConnectionListener.opened()");
}
public void disconnected(ConnectionEvent e) {}
public void closed(ConnectionEvent e) {
System.out.println(">>> ConnectionListener.closed()");
}
// implement TransportListener interface
public void messageDelivered(TransportEvent e) {
System.out.println(">>> TransportListener.messageDelivered().");
System.out.println(" Valid Addresses:");
Address[] valid = e.getValidSentAddresses();
if (valid != null) {
for (int i = 0; i < valid.length; i++)
System.out.println(" " + valid[i]);
}
}
public void messageNotDelivered(TransportEvent e) {
System.out.println(">>> TransportListener.messageNotDelivered().");
System.out.println(" Invalid Addresses:");
Address[] invalid = e.getInvalidAddresses();
if (invalid != null) {
for (int i = 0; i < invalid.length; i++)
System.out.println(" " + invalid[i]);
}
}
public void messagePartiallyDelivered(TransportEvent e) {
System.out.println(">>> TransportListener.messagePartiallyDelivered().");
System.out.println(" Valid Addresses:");
Address[] valid = e.getValidSentAddresses();
if (valid != null) {
for (int i = 0; i < valid.length; i++)
System.out.println(" " + valid[i]);
}
System.out.println(" Valid Unsent Addresses:");
Address[] unsent = e.getValidUnsentAddresses();
if (unsent != null) {
for (int i = 0; i < unsent.length; i++)
System.out.println(" " + unsent[i]);
}
System.out.println(" Invalid Addresses:");
Address[] invalid = e.getInvalidAddresses();
if (invalid != null) {
for (int i = 0; i < invalid.length; i++)
System.out.println(" " + invalid[i]);
}
}
private static void usage() {
System.out.println(
"usage: java transport \"<to1>[, <to2>]*\" <from> <smtp> true|false");
System.out.println(
"example: java transport \"joe@machine, jane\" senderaddr smtphost false");
}
}

View File

@ -0,0 +1,308 @@
/*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
/*
* Demo app that exercises the Message interfaces.
* Access message given its UID.
* Show information about and contents of messages.
*
* @author John Mani
* @author Bill Shannon
*/
public class uidmsgshow {
static String protocol;
static String host = null;
static String user = null;
static String password = null;
static String mbox = "INBOX";
static String url = null;
static boolean verbose = false;
public static void main(String argv[]) {
long uid = -1;
int optind;
for (optind = 0; optind < argv.length; optind++) {
if (argv[optind].equals("-T")) {
protocol = argv[++optind];
} else if (argv[optind].equals("-H")) {
host = argv[++optind];
} else if (argv[optind].equals("-U")) {
user = argv[++optind];
} else if (argv[optind].equals("-P")) {
password = argv[++optind];
} else if (argv[optind].equals("-v")) {
verbose = true;
} else if (argv[optind].equals("-f")) {
mbox = argv[++optind];
} else if (argv[optind].equals("-L")) {
url = argv[++optind];
} else if (argv[optind].equals("--")) {
optind++;
break;
} else if (argv[optind].startsWith("-")) {
System.out.println("Usage: uidmsgshow [-L url] [-T protocol] [-H host] [-U user] [-P password] [-f mailbox] [uid] [-v]");
System.exit(1);
} else {
break;
}
}
try {
if (optind < argv.length)
uid = Long.parseLong(argv[optind]);
// Get a Properties object
Properties props = System.getProperties();
// Get a Session object
Session session = Session.getInstance(props, null);
// session.setDebug(true);
// Get a Store object
Store store = null;
if (url != null) {
URLName urln = new URLName(url);
store = session.getStore(urln);
store.connect();
} else {
if (protocol != null)
store = session.getStore(protocol);
else
store = session.getStore();
// Connect
if (host != null || user != null || password != null)
store.connect(host, user, password);
else
store.connect();
}
// Open the Folder
Folder folder = store.getDefaultFolder();
if (folder == null) {
System.out.println("No default folder");
System.exit(1);
}
folder = folder.getFolder(mbox);
if (!folder.exists()) {
System.out.println(mbox + " does not exist");
System.exit(1);
}
if (!(folder instanceof UIDFolder)) {
System.out.println(
"This Provider or this folder does not support UIDs");
System.exit(1);
}
UIDFolder ufolder = (UIDFolder)folder;
folder.open(Folder.READ_WRITE);
int totalMessages = folder.getMessageCount();
if (totalMessages == 0) {
System.out.println("Empty folder");
folder.close(false);
store.close();
System.exit(1);
}
if (verbose) {
int newMessages = folder.getNewMessageCount();
System.out.println("Total messages = " + totalMessages);
System.out.println("New messages = " + newMessages);
System.out.println("-------------------------------");
}
if (uid == -1) {
// Attributes & Flags for ALL messages ..
Message[] msgs =
ufolder.getMessagesByUID(1, UIDFolder.LASTUID);
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.FLAGS);
fp.add("X-Mailer");
folder.fetch(msgs, fp);
for (int i = 0; i < msgs.length; i++) {
System.out.println("--------------------------");
System.out.println("MESSAGE UID #" +
ufolder.getUID(msgs[i]) + ":");
dumpEnvelope(msgs[i]);
// dumpPart(msgs[i]);
}
} else {
System.out.println("Getting message UID: " + uid);
Message m = ufolder.getMessageByUID(uid);
if (m != null)
dumpPart(m);
else
System.out.println(
"This Message does not exist on this folder");
}
folder.close(false);
store.close();
} catch (Exception ex) {
System.out.println("Oops, got exception! " + ex.getMessage());
ex.printStackTrace();
}
System.exit(1);
}
public static void dumpPart(Part p) throws Exception {
if (p instanceof Message)
dumpEnvelope((Message)p);
/* Dump input stream
InputStream is = new BufferedInputStream(p.getInputStream());
int c;
while ((c = is.read()) != -1)
System.out.write(c);
*/
System.out.println("CONTENT-TYPE: " + p.getContentType());
Object o = p.getContent();
if (o instanceof String) {
System.out.println("This is a String");
System.out.println("---------------------------");
System.out.println((String)o);
} else if (o instanceof Multipart) {
System.out.println("This is a Multipart");
System.out.println("---------------------------");
Multipart mp = (Multipart)o;
int count = mp.getCount();
for (int i = 0; i < count; i++)
dumpPart(mp.getBodyPart(i));
} else if (o instanceof Message) {
System.out.println("This is a Nested Message");
System.out.println("---------------------------");
dumpPart((Part)o);
} else if (o instanceof InputStream) {
System.out.println("This is just an input stream");
System.out.println("---------------------------");
InputStream is = (InputStream)o;
int c;
while ((c = is.read()) != -1)
System.out.write(c);
}
}
public static void dumpEnvelope(Message m) throws Exception {
System.out.println("This is the message envelope");
System.out.println("---------------------------");
Address[] a;
// FROM
if ((a = m.getFrom()) != null) {
for (int j = 0; j < a.length; j++)
System.out.println("FROM: " + a[j].toString());
}
// TO
if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
for (int j = 0; j < a.length; j++)
System.out.println("TO: " + a[j].toString());
}
// SUBJECT
System.out.println("SUBJECT: " + m.getSubject());
// DATE
Date d = m.getSentDate();
System.out.println("SendDate: " +
(d != null ? d.toString() : "UNKNOWN"));
// SIZE
System.out.println("Size: " + m.getSize());
// FLAGS:
Flags flags = m.getFlags();
StringBuffer sb = new StringBuffer();
Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags
boolean first = true;
for (int i = 0; i < sf.length; i++) {
String s;
Flags.Flag f = sf[i];
if (f == Flags.Flag.ANSWERED)
s = "\\Answered";
else if (f == Flags.Flag.DELETED)
s = "\\Deleted";
else if (f == Flags.Flag.DRAFT)
s = "\\Draft";
else if (f == Flags.Flag.FLAGGED)
s = "\\Flagged";
else if (f == Flags.Flag.RECENT)
s = "\\Recent";
else if (f == Flags.Flag.SEEN)
s = "\\Seen";
else
continue; // skip it
if (first)
first = false;
else
sb.append(' ');
sb.append(s);
}
String[] uf = flags.getUserFlags(); // get the user flag strings
for (int i = 0; i < uf.length; i++) {
if (first)
first = false;
else
sb.append(' ');
sb.append(uf[i]);
}
System.out.println("FLAGS = " + sb.toString());
// X-MAILER
String[] hdrs = m.getHeader("X-Mailer");
if (hdrs != null)
System.out.println("X-Mailer: " + hdrs[0]);
else
System.out.println("X-Mailer NOT available");
}
}

View File

@ -0,0 +1,57 @@
@echo off
REM
REM Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
REM
REM Redistribution and use in source and binary forms, with or without
REM modification, are permitted provided that the following conditions
REM are met:
REM
REM - Redistributions of source code must retain the above copyright
REM notice, this list of conditions and the following disclaimer.
REM
REM - Redistributions in binary form must reproduce the above copyright
REM notice, this list of conditions and the following disclaimer in the
REM documentation and/or other materials provided with the distribution.
REM
REM - Neither the name of Oracle nor the names of its
REM contributors may be used to endorse or promote products derived
REM from this software without specific prior written permission.
REM
REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
REM IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
REM THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
REM PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
REM CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
REM EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
REM PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
REM PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
REM LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
REM NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
REM SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REM
mkdir src\docroot\WEB-INF\classes
mkdir src\docroot\WEB-INF\classes\demo
mkdir src\docroot\WEB-INF\lib
cd src\classes
echo compiling classes directory
javac -d ..\docroot\WEB-INF\classes demo\*.java
cd ..\taglib
echo compiling lib directory
javac -classpath "..\docroot\WEB-INF\classes;%CLASSPATH%" demo\*.java
echo creating tag library archive
jar cvf ..\docroot\WEB-INF\lib\taglib.jar META-INF demo\*.class
del demo\*.class
cd ..\docroot
echo creating web archive
jar cvf ..\..\javamail.war index.html *.jsp WEB-INF
cd WEB-INF\classes\demo
del *.*
cd ..
rmdir demo
cd ..
rmdir classes
cd lib
del *.*
cd ..
rmdir lib
cd ..\..\..

View File

@ -0,0 +1,48 @@
#
# Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# - Neither the name of Oracle nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
mkdir src/docroot/WEB-INF/classes
mkdir src/docroot/WEB-INF/lib
cd src/classes
echo "compiling classes directory"
javac -d ../docroot/WEB-INF/classes demo/*.java
cd ../taglib
echo "compiling lib directroy"
javac -classpath ../docroot/WEB-INF/classes:$CLASSPATH demo/*.java
echo "creating tag library archive"
jar cvf ../docroot/WEB-INF/lib/taglib.jar META-INF demo/*.class
rm demo/*.class
cd ../docroot
echo "creating web archive"
jar cvf ../../javamail.war index.html *.jsp WEB-INF
rm -r WEB-INF/classes
rm -r WEB-INF/lib
cd ../..

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2001-2011 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* This servlet gets the input stream for a given msg part and
* pushes it out to the browser with the correct content type.
* Used to display attachments and relies on the browser's
* content handling capabilities.
*/
public class AttachmentServlet extends HttpServlet {
/**
* This method handles the GET requests from the client.
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
HttpSession session = request.getSession();
ServletOutputStream out = response.getOutputStream();
int msgNum = Integer.parseInt(request.getParameter("message"));
int partNum = Integer.parseInt(request.getParameter("part"));
MailUserBean mailuser = (MailUserBean)session.getAttribute("mailuser");
// check to be sure we're still logged in
if (mailuser.isLoggedIn()) {
try {
Message msg = mailuser.getFolder().getMessage(msgNum);
Multipart multipart = (Multipart)msg.getContent();
Part part = multipart.getBodyPart(partNum);
String sct = part.getContentType();
if (sct == null) {
out.println("invalid part");
return;
}
ContentType ct = new ContentType(sct);
response.setContentType(ct.getBaseType());
InputStream is = part.getInputStream();
int i;
while ((i = is.read()) != -1)
out.write(i);
out.flush();
out.close();
} catch (MessagingException ex) {
throw new ServletException(ex.getMessage());
}
} else {
getServletConfig().getServletContext().
getRequestDispatcher("/index.html").
forward(request, response);
}
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* This servlet is used to determine whether the user is logged in before
* forwarding the request to the selected URL.
*/
public class FilterServlet extends HttpServlet {
/**
* This method handles the "POST" submission from two forms: the
* login form and the message compose form.
*/
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
String servletPath = request.getServletPath();
servletPath = servletPath.concat(".jsp");
getServletConfig().getServletContext().
getRequestDispatcher("/" + servletPath).forward(request, response);
}
/**
* This method handles the GET requests from the client.
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// check to be sure we're still logged in
// before forwarding the request.
HttpSession session = request.getSession();
MailUserBean mailuser = (MailUserBean)session.getAttribute("mailuser");
String servletPath = request.getServletPath();
servletPath = servletPath.concat(".jsp");
if (mailuser.isLoggedIn())
getServletConfig().getServletContext().
getRequestDispatcher("/" + servletPath).
forward(request, response);
else
getServletConfig().getServletContext().
getRequestDispatcher("/index.html").
forward(request, response);
}
}

View File

@ -0,0 +1,210 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import java.util.*;
import javax.mail.*;
import javax.naming.*;
/**
* This JavaBean is used to store mail user information.
*/
public class MailUserBean {
private Folder folder;
private String hostname;
private String username;
private String password;
private Session session;
private Store store;
private URLName url;
private String protocol = "imap";
private String mbox = "INBOX";
public MailUserBean(){}
/**
* Returns the javax.mail.Folder object.
*/
public Folder getFolder() {
return folder;
}
/**
* Returns the number of messages in the folder.
*/
public int getMessageCount() throws MessagingException {
return folder.getMessageCount();
}
/**
* hostname getter method.
*/
public String getHostname() {
return hostname;
}
/**
* hostname setter method.
*/
public void setHostname(String hostname) {
this.hostname = hostname;
}
/**
* username getter method.
*/
public String getUsername() {
return username;
}
/**
* username setter method.
*/
public void setUsername(String username) {
this.username = username;
}
/**
* password getter method.
*/
public String getPassword() {
return password;
}
/**
* password setter method.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* session getter method.
*/
public Session getSession() {
return session;
}
/**
* session setter method.
*/
public void setSession(Session session) {
this.session = session;
}
/**
* store getter method.
*/
public Store getStore() {
return store;
}
/**
* store setter method.
*/
public void setStore(Store store) {
this.store = store;
}
/**
* url getter method.
*/
public URLName getUrl() {
return url;
}
/**
* Method for checking if the user is logged in.
*/
public boolean isLoggedIn() {
return store.isConnected();
}
/**
* Method used to login to the mail host.
*/
public void login() throws Exception {
url = new URLName(protocol, getHostname(), -1, mbox,
getUsername(), getPassword());
/*
* First, try to get the session from JNDI,
* as would be done under J2EE.
*/
try {
InitialContext ic = new InitialContext();
Context ctx = (Context)ic.lookup("java:comp/env");
session = (Session)ctx.lookup("MySession");
} catch (Exception ex) {
// ignore it
}
// if JNDI fails, try the old way that should work everywhere
if (session == null) {
Properties props = null;
try {
props = System.getProperties();
} catch (SecurityException sex) {
props = new Properties();
}
session = Session.getInstance(props, null);
}
store = session.getStore(url);
store.connect();
folder = store.getFolder(url);
folder.open(Folder.READ_WRITE);
}
/**
* Method used to login to the mail host.
*/
public void login(String hostname, String username, String password)
throws Exception {
this.hostname = hostname;
this.username = username;
this.password = password;
login();
}
/**
* Method used to logout from the mail host.
*/
public void logout() throws MessagingException {
folder.close(false);
store.close();
store = null;
session = null;
}
}

View File

@ -0,0 +1,87 @@
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<!--
Copyright (c) 2010-2012 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<web-app>
<display-name>JspDemo</display-name>
<description>no description</description>
<servlet>
<servlet-name>FilterServlet</servlet-name>
<display-name>FilterServlet</display-name>
<description>no description</description>
<servlet-class>demo.FilterServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>AttachmentServlet</servlet-name>
<display-name>AttachmentServlet</display-name>
<description>no description</description>
<servlet-class>demo.AttachmentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FilterServlet</servlet-name>
<url-pattern>/compose</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FilterServlet</servlet-name>
<url-pattern>/errordetails</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FilterServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FilterServlet</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FilterServlet</servlet-name>
<url-pattern>/send</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FilterServlet</servlet-name>
<url-pattern>/messageheaders</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FilterServlet</servlet-name>
<url-pattern>/messagecontent</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AttachmentServlet</servlet-name>
<url-pattern>/attachment</url-pattern>
</servlet-mapping>
<resource-ref>
<res-ref-name>MySession</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>

View File

@ -0,0 +1,86 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page language="java" %>
<%@ page errorPage="errorpage.jsp" %>
<html>
<head>
<title>JavaMail compose</title>
</head>
<body bgcolor="#ccccff">
<form ACTION="send" METHOD=POST>
<input type="hidden" name="send" value="send">
<p align="center">
<b><font size="4" face="Verdana, Arial, Helvetica">
JavaMail Compose Message</font></b>
<p>
<table border="0" width="100%">
<tr>
<td width="16%" height="22">
<p align="right">
<b><font face="Verdana, Arial, Helvetica">To:</font></b></td>
<td width="84%" height="22">
<% if (request.getParameter("to") != null) { %>
<input type="text" name="to" value="<%= request.getParameter("to") %>" size="30">
<% } else { %>
<input type="text" name="to" size="30">
<% } %>
<font size="1" face="Verdana, Arial, Helvetica">
(separate addresses with commas)</font></td></tr>
<tr>
<td width="16%"><p align="right">
<b><font face="Verdana, Arial, Helvetica">From:</font></b></td>
<td width="84%">
<input type="text" name="from" size="30">
<font size="1" face="Verdana, Arial, Helvetica">
(separate addresses with commas)</font></td></tr>
<tr>
<td width="16%"><p align="right">
<b><font face="Verdana, Arial, Helvetica">Subject:</font></b></td>
<td width="84%">
<input type="text" name="subject" size="55"></td></tr>
<tr>
<td width="16%">&nbsp;</td>
<td width="84%"><textarea name="text" rows="15" cols="53"></textarea></td></tr>
<tr>
<td width="16%" height="32">&nbsp;</td>
<td width="84%" height="32">
<input type="submit" name="Send" value="Send">
<input type="reset" name="Reset" value="Reset"></td></tr>
</table>
</form>
</body>
</html>

View File

@ -0,0 +1,43 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page isErrorPage="true" %>
<html>
<head>
<title>JavaMail errordetails</title>
</head>
<body bgcolor="white">
<%= session.getValue("details") %>
</body>
</html>

View File

@ -0,0 +1,47 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page isErrorPage="true" %>
<html>
<head>
<title>JavaMail errorpage</title>
</head>
<body bgcolor="white">
<form ACTION="errordetails" METHOD=POST>
<% session.putValue("details", exception.toString()); %>
<h2>An error occured while attempting to perform the operation you requested.
</h2>
<input type="submit" name="Error Details" value="Error Details">
</body>
</html>

View File

@ -0,0 +1,66 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page language="java" import="javax.mail.*, demo.MailUserBean" %>
<%@ page errorPage="errorpage.jsp" %>
<jsp:useBean id="mailuser" scope="session" class="demo.MailUserBean" />
<html>
<head>
<title>JavaMail folders</title>
</head>
<body bgcolor="#ccccff">
<center>
<font face="Arial,Helvetica" font size=+3>
<b>Welcome to JavaMail!</b> </font> </center>
<table width="50%" border=0 align=center>
<tr>
<td width="75%" bgcolor="#ffffcc">
<font face="Arial, Helvetica" font size=-1>
<b>FolderName</b></font></td><br>
<td width="25%" bgcolor="#ffffcc">
<font face="Arial, Helvetica" font size=-1>
<b>Messages</b></font></td><br>
</tr>
<tr>
<td width="75%" bgcolor="#ffffff">
<a href="messageheaders">Inbox</a></td><br>
<td width="25%" bgcolor="#ffffff">
<%= mailuser.getMessageCount() %>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,114 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<!--
Copyright (c) 1998-2011 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<TITLE>JavaMail</TITLE>
</HEAD>
<BODY BGCOLOR="#CCCCFF">
<FORM ACTION="login" METHOD=POST ENCTYPE="application/x-www-form-urlencoded">
<P ALIGN="CENTER"><B><FONT SIZE="5" FACE="Arial, Helvetica">Welcome to JavaMail</FONT></B></P>
<P ALIGN="CENTER"><B><FONT SIZE="5" FACE="Arial, Helvetica">HTML Email Reader Demo</FONT></B></P>
<CENTER>
<P>
<TABLE BORDER="0" WIDTH="100%">
<TR>
<TD WIDTH="40%">
<P ALIGN="RIGHT"><FONT FACE="Arial, Helvetica">IMAP Hostname:</FONT>
</TD>
<TD WIDTH="60%"><INPUT TYPE="TEXT" NAME="hostname" SIZE="25"></TD>
</TR>
<TR>
<TD WIDTH="40%">
<P ALIGN="RIGHT"><FONT FACE="Arial, Helvetica">Username:</FONT>
</TD>
<TD WIDTH="60%"><INPUT TYPE="TEXT" NAME="username" SIZE="25"></TD>
</TR>
<TR>
<TD WIDTH="40%">
<P ALIGN="RIGHT"><FONT FACE="Arial, Helvetica">Password:</FONT>
</TD>
<TD WIDTH="60%"><INPUT TYPE="PASSWORD" NAME="password" SIZE="25"></TD>
</TR>
</TABLE>
<INPUT TYPE="SUBMIT" VALUE="Login"><INPUT TYPE="RESET" NAME="Reset" VALUE="Reset"></P>
</CENTER>
<P>
<HR ALIGN="CENTER">
</P>
<P><B><I><FONT FACE="Arial, Helvetica">Overview:</FONT></I></B></P>
<FONT SIZE="2" FACE="Arial, Helvetica">
<b>THIS IS A DEMO!!!</b> Please see the webapp.README.txt
file for information on how to
compile and run the web application.<br> <br>
This demo illustrates the use of JavaMail APIs in a 3-tiered web
application. It allows the user to login to an
IMAP store, list all the messages in the INBOX folder, view
selected messages, compose and send a message, and logout.
</FONT>
<P><B><I><FONT FACE="Arial, Helvetica">Features:</FONT></I></B></P>
<UL>
<LI><FONT SIZE="2" FACE="Arial, Helvetica">HTML access to your IMAP mailbox</FONT>
<LI><FONT SIZE="2" FACE="Arial, Helvetica">Proxy-able anywhere HTTP can be proxied</FONT>
<LI><FONT SIZE="2" FACE="Arial, Helvetica">Easy to use</FONT>
<LI><FONT SIZE="2" FACE="Arial, Helvetica">Uses web browser's content handling capabilities</FONT>
</UL>
<P><B><I><FONT FACE="Arial, Helvetica">Limitations:</FONT></I></B></P>
<UL>
<LI><FONT SIZE="2" FACE="Arial, Helvetica">Only INBOX support (no user folders)</FONT>
<LI><FONT SIZE="2" FACE="Arial, Helvetica">Can't delete, copy, move, print, save, forward, reply to, search in
messages --<BR>
but it could be done</FONT>
<LI><FONT SIZE="2" FACE="Arial, Helvetica">Doesn't check for new messages (have to log out and log back it)</FONT>
</UL>
<P>
<HR ALIGN="CENTER">
</P>
<P><FONT FACE="Arial, Helvetica">Feedback to </FONT><A HREF="mailto:javamail_ww@oracle.com"><FONT FACE="Arial, Helvetica">javamail_ww@oracle.com</FONT></A>
</FORM>
</BODY>
</HTML>

View File

@ -0,0 +1,56 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page language="java" import="demo.MailUserBean" %>
<%@ page errorPage="errorpage.jsp" %>
<jsp:useBean id="mailuser" scope="session" class="demo.MailUserBean" />
<html>
<head>
<title>JavaMail login</title>
</head>
<body bgcolor="white">
<%
mailuser.login(request.getParameter("hostname"),
request.getParameter("username"),
request.getParameter("password"));
session.setAttribute("folder", mailuser.getFolder());
%>
<jsp:forward page="folders.jsp" />
</body>
</html>

View File

@ -0,0 +1,49 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page language="java" import="demo.MailUserBean" %>
<%@ page errorPage="errorpage.jsp" %>
<jsp:useBean id="mailuser" scope="session" class="demo.MailUserBean" />
<html>
<head>
<title>JavaMail logout</title>
</head>
<% mailuser.logout(); %>
<body>
<h2>Logged out OK</h2><a href=index.html>click here to login</a>
</body>
</html>

View File

@ -0,0 +1,117 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page language="java" import="demo.MessageInfo, demo.AttachmentInfo" %>
<%@ page errorPage="errorpage.jsp" %>
<%@ taglib uri="http://java.sun.com/products/javamail/demo/webapp"
prefix="javamail" %>
<html>
<head>
<title>JavaMail messagecontent</title>
</head>
<javamail:message
id="msginfo"
folder="folder"
num="<%= request.getParameter(\"message\") %>"
/>
<body bgcolor="#ccccff">
<center><font face="Arial,Helvetica" font size="+3">
<b>Message<sp>
<sp>in folder /INBOX</b></font></center><p>
<%-- first, display this message's headers --%>
<b>Date:</b>
<%= msginfo.getSentDate() %>
<br>
<% if (msginfo.hasFrom()) { %>
<b>From:</b>
<a href="compose?to=<%= msginfo.getReplyTo() %>"
target="reply<%= msginfo.getNum() %>">
<%= msginfo.getFrom() %>
</a>
<br>
<% } %>
<% if (msginfo.hasTo()) { %>
<b>To:</b>
<%= msginfo.getTo() %>
<br>
<% } %>
<% if (msginfo.hasCc()) { %>
<b>CC:</b>
<%= msginfo.getCc() %>
<br>
<% } %>
<b>Subject:</b>
<% if (msginfo.hasSubject()) { %>
<%= msginfo.getSubject() %>
<% } %>
<br>
<pre>
<%= msginfo.getBody() %>
</pre>
<% if (msginfo.hasAttachments()) { %>
<javamail:listattachments
id="attachment"
messageinfo="msginfo">
<p><hr>
<b>Attachment Type:</b>
<%= attachment.getAttachmentType() %>
<br>
<% if (attachment.hasMimeType("text/plain") &&
attachment.isInline()){ %>
<pre>
<%= attachment.getContent() %>
</pre>
<% } else { %>
<b>Filename:</b>
<%= attachment.getFilename() %>
<br>
<b>Description:</b>
<%= attachment.getDescription() %>
<br>
<a href="attachment?message=
<%= msginfo.getNum() %>&part=<%= attachment.getNum() %>">
Display Attachment</a>
<% } %>
</javamail:listattachments>
<% } %>
</body>
</html>

View File

@ -0,0 +1,103 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page language="java" import="demo.MessageInfo" %>
<%@ page errorPage="errorpage.jsp" %>
<%@ taglib uri="http://java.sun.com/products/javamail/demo/webapp"
prefix="javamail" %>
<html>
<head>
<title>JavaMail messageheaders</title>
</head>
<body bgcolor="#ccccff"><hr>
<center><font face="Arial,Helvetica" font size="+3">
<b>Folder INBOX</b></font></center><p>
<font face="Arial,Helvetica" font size="+3">
<b><a href="logout">Logout</a>
<a href="compose" target="compose">Compose</a>
</b></font>
<hr>
<table cellpadding=1 cellspacing=1 width="100%" border=1>
<tr>
<td width="25%" bgcolor="ffffcc">
<font face="Arial,Helvetica" font size="+1">
<b>Sender</b></font></td>
<td width="15%" bgcolor="ffffcc">
<font face="Arial,Helvetica" font size="+1">
<b>Date</b></font></td>
<td bgcolor="ffffcc">
<font face="Arial,Helvetica" font size="+1">
<b>Subject</b></font></td>
</tr>
<javamail:listmessages
id="msginfo"
folder="folder">
<%-- from --%>
<tr valign=middle>
<td width="25%" bgcolor="ffffff">
<font face="Arial,Helvetica">
<% if (msginfo.hasFrom()) { %>
<%= msginfo.getFrom() %>
</font>
<% } else { %>
<font face="Arial,Helvetica,sans-serif">
Unknown
<% } %>
</font></td>
<%-- date --%>
<td nowrap width="15%" bgcolor="ffffff">
<font face="Arial,Helvetica">
<%= msginfo.getDate() %>
</font></td>
<%-- subject & link --%>
<td bgcolor="ffffff">
<font face="Arial,Helvetica">
<a href="messagecontent?message=<%= msginfo.getNum() %>">
<% if (msginfo.hasSubject()) { %>
<%= msginfo.getSubject() %>
<% } else { %>
<i>No Subject</i>
<% } %>
</a>
</font></td>
</tr>
</javamail:listmessages>
</table>
</body>
</html>

View File

@ -0,0 +1,57 @@
<%--
Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Oracle nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--%>
<%@ page language="java" %>
<%@ page errorPage="errorpage.jsp" %>
<%@ taglib uri="http://java.sun.com/products/javamail/demo/webapp"
prefix="javamail" %>
<html>
<head>
<title>JavaMail send</title>
</head>
<body bgcolor="white">
<javamail:sendmail
recipients="<%= request.getParameter(\"to\") %>"
sender="<%= request.getParameter(\"from\") %>"
subject="<%= request.getParameter(\"subject\") %>"
>
<%= request.getParameter("text") %>
</javamail:sendmail>
<h1>Message sent successfully</h1>
</body>
</html>

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 2010-2017 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://oss.oracle.com/licenses/CDDL+GPL-1.1
or LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>javamail</shortname>
<uri>http://java.sun.com/products/javamail/demo/webapp</uri>
<tag>
<name>listattachments</name>
<tagclass>demo.ListAttachmentsTag</tagclass>
<teiclass>demo.ListAttachmentsTEI</teiclass>
<bodycontent>JSP</bodycontent>
<info>
A listattachments tag
</info>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>messageinfo</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>listmessages</name>
<tagclass>demo.ListMessagesTag</tagclass>
<teiclass>demo.ListMessagesTEI</teiclass>
<bodycontent>JSP</bodycontent>
<info>
A listmessages tag
</info>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>folder</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>session</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>message</name>
<tagclass>demo.MessageTag</tagclass>
<teiclass>demo.MessageTEI</teiclass>
<bodycontent>empty</bodycontent>
<info>
A message tag
</info>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>folder</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>session</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>num</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>sendmail</name>
<tagclass>demo.SendTag</tagclass>
<bodycontent>JSP</bodycontent>
<info>
A sendmail tag
</info>
<attribute>
<name>host</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>recipients</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>sender</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>subject</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2001-2011 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* Used to store attachment information.
*/
public class AttachmentInfo {
private Part part;
private int num;
/**
* Returns the attachment's content type.
*/
public String getAttachmentType() throws MessagingException {
String contentType;
if ((contentType = part.getContentType()) == null)
return "invalid part";
else
return contentType;
}
/**
* Returns the attachment's content (if it is plain text).
*/
public String getContent() throws IOException, MessagingException {
if (hasMimeType("text/plain"))
return (String)part.getContent();
else
return "";
}
/**
* Returns the attachment's description.
*/
public String getDescription() throws MessagingException {
String description;
if ((description = part.getDescription()) != null)
return description;
else
return "";
}
/**
* Returns the attachment's filename.
*/
public String getFilename() throws MessagingException {
String filename;
if ((filename = part.getFileName()) != null)
return filename;
else
return "";
}
/**
* Returns the attachment number.
*/
public String getNum() {
return (Integer.toString(num));
}
/**
* Method for checking if the attachment has a description.
*/
public boolean hasDescription() throws MessagingException {
return (part.getDescription() != null);
}
/**
* Method for checking if the attachment has a filename.
*/
public boolean hasFilename() throws MessagingException {
return (part.getFileName() != null);
}
/**
* Method for checking if the attachment has the desired mime type.
*/
public boolean hasMimeType(String mimeType) throws MessagingException {
return part.isMimeType(mimeType);
}
/**
* Method for checking the content disposition.
*/
public boolean isInline() throws MessagingException {
if (part.getDisposition() != null)
return part.getDisposition().equals(Part.INLINE);
else
return true;
}
/**
* Method for mapping a message part to this AttachmentInfo class.
*/
public void setPart(int num, Part part)
throws MessagingException, ParseException {
this.part = part;
this.num = num;
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Extra information class to support the scripting variable created by the
* ListAttachmentsTag class. The scope of the variable is limited to the body
* of the tag.
*/
public class ListAttachmentsTEI extends TagExtraInfo {
public ListAttachmentsTEI() {
super();
}
public VariableInfo[] getVariableInfo(TagData data) {
VariableInfo info = new VariableInfo(data.getId(),"AttachmentInfo",
true, VariableInfo.NESTED);
VariableInfo[] varInfo = { info };
return varInfo;
}
}

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Custom tag for listing message attachments. The scripting variable is only
* within the body of the tag.
*/
public class ListAttachmentsTag extends BodyTagSupport {
private String messageinfo;
private int partNum = 1;
private int numParts = 0;
private AttachmentInfo attachmentinfo;
private MessageInfo messageInfo;
private Multipart multipart;
/**
* messageinfo attribute getter method.
*/
public String getMessageinfo() {
return messageinfo;
}
/**
* messageinfo attribute setter method.
*/
public void setMessageinfo(String messageinfo) {
this.messageinfo = messageinfo;
}
/**
* Method for processing the start of the tag.
*/
public int doStartTag() throws JspException {
messageInfo = (MessageInfo)pageContext.getAttribute(getMessageinfo());
attachmentinfo = new AttachmentInfo();
try {
multipart = (Multipart)messageInfo.getMessage().getContent();
numParts = multipart.getCount();
} catch (Exception ex) {
throw new JspException(ex.getMessage());
}
getPart();
return BodyTag.EVAL_BODY_TAG;
}
/**
* Method for processing the body content of the tag.
*/
public int doAfterBody() throws JspException {
BodyContent body = getBodyContent();
try {
body.writeOut(getPreviousOut());
} catch (IOException e) {
throw new JspTagException("IterationTag: " + e.getMessage());
}
// clear up so the next time the body content is empty
body.clearBody();
partNum++;
if (partNum < numParts) {
getPart();
return BodyTag.EVAL_BODY_TAG;
} else {
return BodyTag.SKIP_BODY;
}
}
/**
* Helper method for retrieving message parts.
*/
private void getPart() throws JspException {
try {
attachmentinfo.setPart(partNum, multipart.getBodyPart(partNum));
pageContext.setAttribute(getId(), attachmentinfo);
} catch (Exception ex) {
throw new JspException(ex.getMessage());
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Extra information class to support the scripting variable created by the
* ListMessagesTag class. The scope of the variable is limited to the body
* of the tag.
*/
public class ListMessagesTEI extends TagExtraInfo {
public ListMessagesTEI() {
super();
}
public VariableInfo[] getVariableInfo(TagData data) {
VariableInfo info = new VariableInfo(data.getId(),"MessageInfo",
true, VariableInfo.NESTED);
VariableInfo[] varInfo = { info };
return varInfo;
}
}

View File

@ -0,0 +1,139 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Custom tag for listing messages. The scripting variable is only
* within the body of the tag.
*/
public class ListMessagesTag extends BodyTagSupport {
private String folder;
private String session;
private int msgNum = 0;
private int messageCount = 0;
private Message message;
private Message[] messages;
private MessageInfo messageinfo;
/**
* folder attribute getter method.
*/
public String getFolder() {
return folder;
}
/**
* session attribute getter method.
*/
public String getSession() {
return session;
}
/**
* folder setter method.
*/
public void setFolder(String folder) {
this.folder = folder;
}
/**
* session attribute setter method.
*/
public void setSession(String session) {
this.session = session;
}
/**
* Method for processing the start of the tag.
*/
public int doStartTag() throws JspException {
messageinfo = new MessageInfo();
try {
Folder folder = (Folder)pageContext.getAttribute(
getFolder(), PageContext.SESSION_SCOPE);
FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.DELETED), false);
messages = folder.search(ft);
messageCount = messages.length;
msgNum = 0;
} catch (Exception ex) {
throw new JspException(ex.getMessage());
}
if (messageCount > 0) {
getMessage();
return BodyTag.EVAL_BODY_TAG;
} else
return BodyTag.SKIP_BODY;
}
/**
* Method for processing the body content of the tag.
*/
public int doAfterBody() throws JspException {
BodyContent body = getBodyContent();
try {
body.writeOut(getPreviousOut());
} catch (IOException e) {
throw new JspTagException("IterationTag: " + e.getMessage());
}
// clear up so the next time the body content is empty
body.clearBody();
if (msgNum < messageCount) {
getMessage();
return BodyTag.EVAL_BODY_TAG;
} else {
return BodyTag.SKIP_BODY;
}
}
/**
* Helper method for retrieving messages.
*/
private void getMessage() throws JspException {
message = messages[msgNum++];
messageinfo.setMessage(message);
pageContext.setAttribute(getId(), messageinfo);
}
}

View File

@ -0,0 +1,284 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import java.text.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* Used to store message information.
*/
public class MessageInfo {
private Message message;
/**
* Returns the bcc field.
*/
public String getBcc() throws MessagingException {
return formatAddresses(
message.getRecipients(Message.RecipientType.BCC));
}
/**
* Returns the body of the message (if it's plain text).
*/
public String getBody() throws MessagingException, java.io.IOException {
Object content = message.getContent();
if (message.isMimeType("text/plain")) {
return (String)content;
} else if (message.isMimeType("multipart/alternative")) {
Multipart mp = (Multipart)message.getContent();
int numParts = mp.getCount();
for (int i = 0; i < numParts; ++i) {
if (mp.getBodyPart(i).isMimeType("text/plain"))
return (String)mp.getBodyPart(i).getContent();
}
return "";
} else if (message.isMimeType("multipart/*")) {
Multipart mp = (Multipart)content;
if (mp.getBodyPart(0).isMimeType("text/plain"))
return (String)mp.getBodyPart(0).getContent();
else
return "";
} else
return "";
}
/**
* Returns the cc field.
*/
public String getCc() throws MessagingException {
return formatAddresses(
message.getRecipients(Message.RecipientType.CC));
}
/**
* Returns the date the message was sent (or received if the sent date
* is null.
*/
public String getDate() throws MessagingException {
Date date;
SimpleDateFormat df = new SimpleDateFormat("EE M/d/yy");
if ((date = message.getSentDate()) != null)
return (df.format(date));
else if ((date = message.getReceivedDate()) != null)
return (df.format(date));
else
return "";
}
/**
* Returns the from field.
*/
public String getFrom() throws MessagingException {
return formatAddresses(message.getFrom());
}
/**
* Returns the address to reply to.
*/
public String getReplyTo() throws MessagingException {
Address[] a = message.getReplyTo();
if (a.length > 0)
return ((InternetAddress)a[0]).getAddress();
else
return "";
}
/**
* Returns the javax.mail.Message object.
*/
public Message getMessage() {
return message;
}
/**
* Returns the message number.
*/
public String getNum() {
return (Integer.toString(message.getMessageNumber()));
}
/**
* Returns the received date field.
*/
public String getReceivedDate() throws MessagingException {
if (hasReceivedDate())
return (message.getReceivedDate().toString());
else
return "";
}
/**
* Returns the sent date field.
*/
public String getSentDate() throws MessagingException {
if (hasSentDate())
return (message.getSentDate().toString());
else
return "";
}
/**
* Returns the subject field.
*/
public String getSubject() throws MessagingException {
if (hasSubject())
return message.getSubject();
else
return "";
}
/**
* Returns the to field.
*/
public String getTo() throws MessagingException {
return formatAddresses(
message.getRecipients(Message.RecipientType.TO));
}
/**
* Method for checking if the message has attachments.
*/
public boolean hasAttachments() throws java.io.IOException,
MessagingException {
boolean hasAttachments = false;
if (message.isMimeType("multipart/*")) {
Multipart mp = (Multipart)message.getContent();
if (mp.getCount() > 1)
hasAttachments = true;
}
return hasAttachments;
}
/**
* Method for checking if the message has a bcc field.
*/
public boolean hasBcc() throws MessagingException {
return (message.getRecipients(Message.RecipientType.BCC) != null);
}
/**
* Method for checking if the message has a cc field.
*/
public boolean hasCc() throws MessagingException {
return (message.getRecipients(Message.RecipientType.CC) != null);
}
/**
* Method for checking if the message has a date field.
*/
public boolean hasDate() throws MessagingException {
return (hasSentDate() || hasReceivedDate());
}
/**
* Method for checking if the message has a from field.
*/
public boolean hasFrom() throws MessagingException {
return (message.getFrom() != null);
}
/**
* Method for checking if the message has the desired mime type.
*/
public boolean hasMimeType(String mimeType) throws MessagingException {
return message.isMimeType(mimeType);
}
/**
* Method for checking if the message has a received date field.
*/
public boolean hasReceivedDate() throws MessagingException {
return (message.getReceivedDate() != null);
}
/**
* Method for checking if the message has a sent date field.
*/
public boolean hasSentDate() throws MessagingException {
return (message.getSentDate() != null);
}
/**
* Method for checking if the message has a subject field.
*/
public boolean hasSubject() throws MessagingException {
return (message.getSubject() != null);
}
/**
* Method for checking if the message has a to field.
*/
public boolean hasTo() throws MessagingException {
return (message.getRecipients(Message.RecipientType.TO) != null);
}
/**
* Method for mapping a message to this MessageInfo class.
*/
public void setMessage(Message message) {
this.message = message;
}
/**
* Utility method for formatting msg header addresses.
*/
private String formatAddresses(Address[] addrs) {
if (addrs == null)
return "";
StringBuffer strBuf = new StringBuffer(getDisplayAddress(addrs[0]));
for (int i = 1; i < addrs.length; i++) {
strBuf.append(", ").append(getDisplayAddress(addrs[i]));
}
return strBuf.toString();
}
/**
* Utility method which returns a string suitable for msg header display.
*/
private String getDisplayAddress(Address a) {
String pers = null;
String addr = null;
if (a instanceof InternetAddress &&
((pers = ((InternetAddress)a).getPersonal()) != null)) {
addr = pers + " "+"&lt;"+((InternetAddress)a).getAddress()+"&gt;";
} else
addr = a.toString();
return addr;
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Extra information class to support the scripting variable created by the
* MessagesTag class. The variable exists outside of the tag.
*
*/
public class MessageTEI extends TagExtraInfo {
public MessageTEI() {
super();
}
public VariableInfo[] getVariableInfo(TagData data) {
VariableInfo info = new VariableInfo(data.getId(),"MessageInfo",
true, VariableInfo.AT_END);
VariableInfo[] varInfo = { info };
return varInfo;
}
}

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2001-2010 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package demo;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Custom tag for retrieving a message.
*/
public class MessageTag extends TagSupport {
private String folder;
private String session;
private int num = 1;
/**
* folder attribute setter method.
*/
public String getFolder() {
return folder;
}
/**
* num attribute getter method.
*/
public String getNum() {
return Integer.toString(num);
}
/**
* session attribute getter method.
*/
public String getSession() {
return session;
}
/**
* folder setter method.
*/
public void setFolder(String folder) {
this.folder = folder;
}
/**
* num attribute setter method.
*/
public void setNum(String num) {
this.num = Integer.parseInt(num);
}
/**
* session attribute setter method.
*/
public void setSession(String session) {
this.session = session;
}
/**
* Method for processing the start of the tag.
*/
public int doStartTag() throws JspException {
MessageInfo messageinfo = new MessageInfo();
try {
Folder f = (Folder)pageContext.getAttribute(
getFolder(), PageContext.SESSION_SCOPE);
Message message = f.getMessage(num);
messageinfo.setMessage(message);
pageContext.setAttribute(getId(), messageinfo);
} catch (Exception ex) {
throw new JspException(ex.getMessage());
}
return SKIP_BODY;
}
}

Some files were not shown because too many files have changed in this diff Show More