001: /* MessageConst.java
002:
003: {{IS_NOTE
004:
005: Purpose: Defines message types
006: Description:
007: History:
008: 2001/4/2 2001/4/2, Tom M. Yeh: Created.
009:
010: }}IS_NOTE
011:
012: Copyright (C) 2001 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.mesg;
020:
021: import java.util.List;
022: import java.util.ArrayList;
023:
024: import org.zkoss.lang.D;
025: import org.zkoss.lang.Objects;
026:
027: /**
028: * Defines the constants of message types.
029: *
030: * @author tomyeh
031: * @see Messages
032: */
033: public interface MessageConst {
034: /** Denotes a non-existent code. */
035: public static final int NULL_CODE = 0;
036:
037: /** The info of each message bundle.
038: * <p>Each bundle is associated with a class and a set of files.
039: */
040: public static class BundleInfo {
041: public final Class klass;
042: public final String filename;
043:
044: private BundleInfo(Class klass, String filename) {
045: this .klass = klass;
046: this .filename = filename;
047: }
048:
049: public String toString() {
050: return "[" + this .klass + ", " + this .filename + ']';
051: }
052: }
053:
054: /** Used to handle the mapping of a message code to a filename.
055: *
056: * <p>FUTURE: we might consider to use hashCode or other to represents
057: * the identifier such that the client will have the same code as the server.
058: */
059: public static class Aide {
060: private static BundleInfo[] _bis = new BundleInfo[0];
061:
062: /** Registers a message filename, and returns an identifier to
063: * represent it.
064: *
065: * <p>The path is assumed to be /metainfo/mesg.
066: *
067: * @param filename the filename without path and extension, e.g, "msgacc"
068: * @return an identifier to represent this message file.
069: */
070: public static final int register(Class klass, String filename) {
071: if (filename.indexOf('/') >= 0
072: || filename.indexOf('.') >= 0)
073: throw new IllegalArgumentException(
074: "Neither path nor extension is allowed: "
075: + filename);
076: if (klass == null)
077: throw new IllegalArgumentException("null class");
078:
079: filename = "/metainfo/mesg/" + filename;
080: final BundleInfo bi = new BundleInfo(klass, filename);
081: synchronized (Aide.class) {
082: final int sz = _bis.length + 1;
083: final List bis = new ArrayList(sz);
084: for (int j = 0; j < _bis.length; ++j) {
085: if (_bis[j].filename.equals(filename)
086: || _bis[j].klass.equals(klass))
087: throw new IllegalStateException(
088: "Replicate message: "
089: + bi
090: + "\nRegistered message files: "
091: + Objects.toString(bis));
092: bis.add(_bis[j]);
093: }
094: bis.add(bi);
095: _bis = (BundleInfo[]) bis.toArray(new BundleInfo[sz]);
096: return (sz << 16); //as the high word; starting from (1<<16)
097: }
098: }
099:
100: /** Returns the filename with path, but without extension, of the
101: * specified message code.
102: */
103: public static final BundleInfo getBundleInfo(int code) {
104: final BundleInfo[] bis = _bis; //so no sync is required
105: final int j = (code >>> 16) - 1; //starting from 1
106: if (j < 0 || j >= bis.length)
107: throw new IllegalArgumentException(
108: "Wrong message code: " + code
109: + "\nRegistered messages: "
110: + Objects.toString(bis));
111: return bis[j];
112: }
113: }
114: }
|