Back to index

im-sdk  12.3.91
Manager.java
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 
00044 package sun.awt.im.iiimp;
00045 
00046 import java.security.AccessController;
00047 import java.security.PrivilegedAction;
00048 
00049 import java.lang.Character.Subset;
00050 import java.awt.im.InputContext;
00051 import sun.awt.im.InputMethodAdapter;
00052 
00053 import java.io.*;
00054 import java.util.*;
00055 import java.awt.*;
00056 import java.awt.event.*;
00057 import javax.swing.*;
00058 import com.sun.iiim.*;
00059 
00063 public class Manager {
00064 
00065     // private variables
00066     private ManageRule rule;
00067     private IIIMPreeditListener preeditListener;
00068     private IIIMCommittedListener committedListener;
00069     private IIIMLookupListener lookupListener;
00070     private IIIMStatusListener statusListener;
00071     private IIIMActionListener actionListener;
00072     private IIIMAuxListener auxListeners;
00073     private IIIMFAdapter adapter;
00074 
00075     static void setPD(ProtocolDriver pd) {
00076        protocolDriver = pd;
00077        String[] ims = pd.getEngineScript();
00078 
00079        if (ims != null) {
00080            for (int i = 0; i < ims.length; i++) {
00081               ruleTable.add(new ManageRule(ims[i]));
00082            }
00083        }
00084     }
00085 
00086     private static ProtocolDriver protocolDriver = null;
00087 
00088     private final static String PCE_CLASSNAME =
00089        "sun.awt.im.iiimp.PCE";
00090 
00091     private final static String DEFAULT_RULE = 
00092        " sun.awt.im.iiimp.ProtocolDriver";
00093 
00094     private final static String TEST_RULE =
00095        "sun.awt.im.iiimp.LWE1 " +
00096        "sun.awt.im.iiimp.LWE2";
00097 
00098     private final static String PCE_TEST_RULE =
00099        PCE_CLASSNAME +
00100        " sun.awt.im.iiimp.PseudoPD";
00101 
00102     private static String defaultRuleString;
00103     private static String currentRuleString;
00104 
00105     public static boolean DEBUG = false;
00106     public static boolean COLOR_SUPPORT = false;
00107     public static boolean NO_STATUS = false;
00108 
00109     // for engine switching
00110     private static IIIMKeyEvent toggleKey = new IIIMKeyEvent("Alt+Shift");
00111     private static IIIMKeyEvent editHotKey = new IIIMKeyEvent("F12");
00112     private static HashSet ruleTable = new HashSet();
00113 
00114     private static void collectRules() {
00115        // local rules
00116        String localRules = getProperty("iiimf.manager.rules",
00117                                    defaultRuleString);
00118        StringTokenizer st = new StringTokenizer(localRules, ",");
00119        while (st.hasMoreTokens()) {
00120            String token = st.nextToken();
00121            ruleTable.add(new ManageRule(token));
00122        }
00123        // remote rules is added when setPD is called.
00124     }
00125 
00126     private Manager() {
00127        initProps();
00128 
00129        DEBUG =
00130            getProperty("iiimf.manager.debug", "false").equals("true") ?
00131            true : false;
00132 
00133        COLOR_SUPPORT =
00134            getProperty("iiimf.gui.color", "false").equals("true") ?
00135            true : false;
00136 
00137        NO_STATUS =
00138            getProperty("iiimf.status.none", "false").equals("true") ?
00139            true : false;
00140 
00141        defaultRuleString =
00142            getProperty("iiimf.manager.rule", DEFAULT_RULE);
00143        currentRuleString =
00144            getProperty("iiimf.manager.rule.userpref", defaultRuleString);
00145     }
00146 
00147     void setManageRule(ManageRule rule) {
00148        this.rule = rule;
00149     }
00150 
00151     void setCCDEF(String ccdef) {
00152        rule.setCCDEF(ccdef);
00153     }
00154 
00155     /*
00156      * Only one Manager exist per one VM.
00157      */
00158     static private Manager manager;
00159     static public Manager getInstance() {
00160        if (manager == null) {
00161            manager = new Manager();
00162            manager.setManageRule(new ManageRule(currentRuleString));
00163            collectRules();
00164        }
00165        return manager;
00166     }
00167 
00168     static private ODClassLoader loader;
00169     static void setLoader(ODClassLoader ld) {
00170        loader = ld;
00171     }
00172 
00173     static public ODClassLoader getLoader() {
00174        return loader;
00175     }
00176 
00177     void setIIIMFAdapter(IIIMFAdapter adapter) {
00178        this.adapter = adapter;
00179     }
00180 
00181     void setIIIMActionListener(IIIMActionListener l) {
00182        // override previous one
00183        actionListener = l;  
00184     }
00185 
00186     void setIIIMPreeditListener(IIIMPreeditListener l) {
00187        // override previous one
00188        preeditListener = l;
00189     }
00190 
00191     IIIMPreeditListener getIIIMPreeditListener() {
00192        return preeditListener;
00193     }
00194 
00195     void setIIIMCommittedListener(IIIMCommittedListener l) {
00196        // override previous one
00197        committedListener = l;
00198     }
00199 
00200     IIIMCommittedListener getIIIMCommittedListener() {
00201        return committedListener;
00202     }
00203 
00204     void setIIIMLookupListener(IIIMLookupListener l) {
00205        // override previous one
00206        lookupListener = l;
00207     }
00208 
00209     void setIIIMStatusListener(IIIMStatusListener l) {
00210        // override previous one
00211        statusListener = l;
00212     }
00213 
00214     void setIIIMAuxListener(IIIMAuxListener l) {
00215        // add existing auxes
00216        auxListeners = IIIMAuxListeners.add(auxListeners, l);
00217     }
00218 
00219     /*
00220      * called from IIIMFAdapter
00221      */
00222     void dispatchEvent(IIIMEvent ev) {
00223        for (int i = 0; i < rule.size(); i++) {
00224            IIIMListener iiimListener = rule.get(i);
00225            if (!ev.isProcessedBy(iiimListener) && !ev.isConsumed()) {
00226               iiimListener.dispatchEvent(ev);
00227               ev.processedBy(iiimListener);
00228            }
00229        }
00230     }
00231 
00232     public void dispatchActionEvent(IIIMActionEvent e) {
00233        switch(e.getType()) {
00234          case IIIMActionEvent.LOOKUP_PROCESSED:
00235            Component c = getClientComponent();
00236            int ch = ((String)e.getArg()).charAt(0);
00237            KeyEvent kev = new KeyEvent(c, KeyEvent.KEY_PRESSED,
00238                                    0, 0, ch, (char)ch);
00239            adapter.dispatchEvent(kev);
00240            break;
00241          default:
00242            for (int i = 0; i < rule.size(); i++) {
00243               IIIMListener iiimListener = rule.get(i);
00244               if (iiimListener instanceof IIIMActionListener &&
00245                   !e.isProcessedBy(iiimListener) && !e.isConsumed()) {
00246                   ((IIIMActionListener)iiimListener).actionPerformed(e);
00247                   e.processedBy(iiimListener);
00248               }
00249            }
00250            break;
00251        }
00252     }
00253 
00254     public void dispatchAuxEvent(IIIMAuxEvent e) {
00255        if (e.getType() == IIIMAuxEvent.SETVALUES) {
00256            // client -> server
00257            if (protocolDriver != null) {
00258               try {
00259                   protocolDriver.sendAuxData(e);
00260               } catch(Exception ex) {
00261                   if (Manager.DEBUG) {
00262                      ex.printStackTrace();
00263                   }
00264               }
00265            }
00266        } else if (auxListeners != null) {
00267            // server -> client
00268            switch(e.getType()) {
00269              case IIIMAuxEvent.START:
00270               auxListeners.auxStart(e);
00271               break;
00272              case IIIMAuxEvent.DONE:
00273               auxListeners.auxDone(e);
00274               break;
00275              case IIIMAuxEvent.DRAW:
00276               auxListeners.auxDraw(e);
00277               break;
00278              default:
00279               System.out.println("Unknown aux event");
00280               break;
00281            }
00282        }
00283     }
00284 
00285     public void dispatchPreeditEvent(IIIMPreeditEvent e) {
00286        if (preeditListener == null) {
00287            return;
00288        }
00289        switch(e.getType()) {
00290          case IIIMPreeditEvent.START:
00291            preeditListener.preeditStart(e);
00292            break;
00293          case IIIMPreeditEvent.DONE:
00294            preeditListener.preeditDone(e);
00295            break;
00296          case IIIMPreeditEvent.DRAW:
00297            preeditListener.preeditDraw(e);
00298            break;
00299          default:
00300            System.out.println(" Unknown preedit event");
00301        }
00302     }
00303 
00304     public void dispatchCommittedEvent(IIIMCommittedEvent e) {
00305        if (committedListener == null) {
00306            return;
00307        }
00308        committedListener.committedPerformed(e);
00309     }
00310 
00311     public void dispatchStatusEvent(IIIMStatusEvent e) {
00312        if (NO_STATUS) {
00313            return;
00314        }
00315 
00316        if (statusListener == null) {
00317            return;
00318        }
00319        switch(e.getType()) {
00320          case IIIMStatusEvent.START:
00321            statusListener.statusStart(e);
00322            break;
00323          case IIIMStatusEvent.DONE:
00324            statusListener.statusDone(e);
00325            break;
00326          case IIIMStatusEvent.DRAW:
00327            statusListener.statusDraw(e);
00328            break;
00329          default:
00330            System.out.println(" Unknown status event");
00331        }
00332     }
00333 
00334     public void dispatchLookupEvent(IIIMLookupEvent e) {
00335        if (lookupListener == null) {
00336            return;
00337        }
00338        switch(e.getType()) {
00339          case IIIMLookupEvent.START:
00340            lookupListener.lookupStart(e);
00341            break;
00342          case IIIMLookupEvent.DONE:
00343            lookupListener.lookupDone(e);
00344            break;
00345          case IIIMLookupEvent.DRAW:
00346            lookupListener.lookupDraw(e);
00347            break;
00348          case IIIMLookupEvent.PROCESS:
00349            lookupListener.lookupProcess(e);
00350            break;
00351          default:
00352            System.out.println("Unknown lookup event");
00353        }
00354     }
00355 
00356     public void markProcessedUpperListener(IIIMEvent e, IIIMListener l) {
00357        for (int i = 0; i < rule.size(); i++) {
00358            IIIMListener iiimListener = rule.get(i);
00359            e.processedBy(iiimListener);
00360            if (iiimListener.equals(rule.get(i))) {
00361               break;
00362            }
00363        }
00364     }
00365 
00366     public Component getClientComponent() {
00367        if (adapter == null)
00368            return null;
00369        
00370        return adapter.getClientComponent();
00371     }
00372        
00373 
00374     private static Properties iiimProps = null;
00375 
00376     private static String userPropsFile;
00377 
00378     static void initProps() {
00379        iiimProps = new Properties();
00380        AccessController.doPrivileged(new PrivilegedAction() {
00381            public Object run() {
00382               String javaHome = System.getProperty("java.home");
00383               String userHome = System.getProperty("user.home");
00384               File f;
00385               InputStream in;
00386 
00387               try {
00388                   // $JAVA_HOME/lib/iiimp.properties
00389                   f = new File(javaHome + File.separator +
00390                              "lib" + File.separator + "iiimp.properties");
00391                   if (f != null && f.canRead()) {
00392                      in = new BufferedInputStream
00393                          (new FileInputStream(f.getPath()));
00394                      iiimProps.load(in);
00395                      in.close();
00396                   }
00397 
00398                   // $HOME/.iiimp
00399                   userPropsFile = userHome + File.separator + ".iiimp";
00400                   f = new File(userPropsFile);
00401                   if (f != null && f.canRead()) {
00402                      in = new BufferedInputStream
00403                          (new FileInputStream(f.getPath()));
00404                      iiimProps.load(in);
00405                      in.close();
00406                   }
00407               } catch(Exception e) {
00408                   if (Manager.DEBUG) {
00409                      e.printStackTrace();
00410                   }
00411               }
00412               return null;
00413            }
00414        });
00415     }
00416        
00417     /*
00418      * set Property, return previous value if exist
00419      */
00420     static String setProperty(String key, String value) {
00421        String ret = (String)iiimProps.setProperty(key, value);
00422        
00423        AccessController.doPrivileged(new PrivilegedAction() {
00424            public Object run() {
00425               File f;
00426               OutputStream out;
00427 
00428               try {
00429                   f = new File(userPropsFile);
00430                   if (f != null && f.canWrite()) {
00431                      out = new BufferedOutputStream
00432                          (new FileOutputStream(f.getPath()));
00433                      iiimProps.store(out, "iiimf property file");
00434                      out.close();
00435                   }
00436               } catch(Exception e) {
00437                   if (Manager.DEBUG) {
00438                      e.printStackTrace();
00439                   }
00440               }
00441               return null;
00442            }
00443        });
00444                   
00445        return ret;
00446     }
00447 
00448     /*
00449      * get Property, return null if the key does not exist
00450      */
00451     static String getProperty(String key) {
00452        return iiimProps.getProperty(key);
00453     }
00454 
00455     /*
00456      * get Property, return def if the  key does not exist
00457      */
00458     static String getProperty(String key, String def) {
00459        return iiimProps.getProperty(key, def);
00460     }
00461 
00462     Locale currentLocale = null;
00463 
00464     Locale getCurrentLocale() {
00465        if (currentLocale != null) {
00466            return currentLocale;
00467        }
00468        return Locale.getDefault();
00469     }
00470 
00472     boolean setLocale(Locale locale) {
00473        currentLocale = locale;
00474        protocolDriver.activate();
00475        return true;
00476     }
00477 
00478     void setCharacterSubsets(Subset[] subsets) {
00479        for (int i = 0; i < rule.size(); i++) {
00480            IIIMListener l = rule.get(i);
00481            if (l instanceof InputMethodAdapter) {
00482               ((InputMethodAdapter)l).setCharacterSubsets(subsets);
00483            }
00484        }
00485     }
00486 
00487     void activate() {
00488        for (int i = 0; i < rule.size(); i++) {
00489            IIIMListener l = rule.get(i);
00490            if (l instanceof InputMethodAdapter) {
00491               ((InputMethodAdapter)l).activate();
00492            }
00493        }
00494        if (statusListener instanceof InputMethodAdapter) {
00495            ((InputMethodAdapter)statusListener).activate();
00496        }
00497        if (lookupListener instanceof InputMethodAdapter) {
00498            ((InputMethodAdapter)lookupListener).activate();
00499        }
00500     }
00501 
00502     void deactivate(boolean isTemporary) {
00503        for (int i = 0; i < rule.size(); i++) {
00504            IIIMListener l = rule.get(i);
00505            if (l instanceof InputMethodAdapter) {
00506               ((InputMethodAdapter)l).deactivate(isTemporary);
00507            }
00508        }
00509        if (statusListener instanceof InputMethodAdapter) {
00510            ((InputMethodAdapter)statusListener).deactivate(isTemporary);
00511        }
00512        if (lookupListener instanceof InputMethodAdapter) {
00513            ((InputMethodAdapter)lookupListener).deactivate(isTemporary);
00514        }
00515     }
00516 
00517     void removeNotify() {
00518        for (int i = 0; i < rule.size(); i++) {
00519            IIIMListener l = rule.get(i);
00520            if (l instanceof InputMethodAdapter) {
00521               ((InputMethodAdapter)l).removeNotify();
00522            }
00523        }
00524     }
00525 
00526     void endComposition() {
00527        for (int i = 0; i < rule.size(); i++) {
00528            IIIMListener l = rule.get(i);
00529            if (l instanceof InputMethodAdapter) {
00530               ((InputMethodAdapter)l).endComposition();
00531            }
00532        }
00533     }
00534 
00535     void dispose() {
00536        for (int i = 0; i < rule.size(); i++) {
00537            IIIMListener l = rule.get(i);
00538            if (l instanceof InputMethodAdapter) {
00539               ((InputMethodAdapter)l).dispose();
00540            }
00541        }
00542        if (statusListener instanceof InputMethodAdapter) {
00543            ((InputMethodAdapter)statusListener).dispose();
00544        }
00545        if (lookupListener instanceof InputMethodAdapter) {
00546            ((InputMethodAdapter)lookupListener).dispose();
00547        }
00548     }
00549 
00550     Object getControlObject() {
00551        for (int i = 0; i < rule.size(); i++) {
00552            IIIMListener l = rule.get(i);
00553            if (l instanceof InputMethodAdapter) {
00554               Object o = ((InputMethodAdapter)l).getControlObject();
00555               if (o != null)
00556                   return o;
00557            }
00558        }
00559        return null;
00560     }
00561 
00562     public Locale[] getAvailableLocales() {
00563        // use Set to prevent duplicate entry
00564        HashSet hs = new HashSet();
00565        for (int i = 0; i < rule.size(); i++) {
00566            IIIMListener l = rule.get(i);
00567            if (l instanceof IMProvider) {
00568               IMProvider imp = (IMProvider)l;
00569               Locale[] la = imp.getSupportLocales();
00570               if (la != null) {
00571                   for (int j = 0; j < la.length; j++) {
00572                      hs.add(la[j]);
00573                   }
00574               }
00575            }
00576        }
00577        Locale[] locales = new Locale[hs.size()];
00578        Iterator iterator = hs.iterator();
00579        int k = 0;
00580        for (; iterator.hasNext();) {
00581            locales[k++] = (Locale)iterator.next();
00582        }
00583        return locales;
00584     }
00585 }
00586            
00587 /*
00588  * Holder class for multiple AuxListener
00589  */
00590 class IIIMAuxListeners implements IIIMAuxListener {
00591 
00592     IIIMAuxListener a, b;   
00593     IIIMAuxListeners(IIIMAuxListener a, IIIMAuxListener b) {
00594        this.a = a; this.b = b;
00595     }
00596 
00597     static IIIMAuxListener add(IIIMAuxListener a, IIIMAuxListener b) {
00598        if (a == null) return b;
00599        if (b == null) return a; 
00600        return new IIIMAuxListeners(a, b);
00601     }
00602 
00603     public void dispatchEvent(IIIMEvent e) {
00604     }
00605 
00606     public void auxStart(IIIMAuxEvent e) {
00607        if (a != null) a.dispatchEvent(e);
00608        if (b != null) b.dispatchEvent(e);
00609     }
00610     public void auxDone(IIIMAuxEvent e) {
00611        if (a != null) a.dispatchEvent(e);
00612        if (b != null) b.dispatchEvent(e);
00613     }
00614     public void auxDraw(IIIMAuxEvent e) {
00615        if (a != null) a.dispatchEvent(e);
00616        if (b != null) b.dispatchEvent(e);
00617     }
00618 
00619 }
00620