001: /*
002: * Copyright (c) 1998-2005 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Sam
027: */
028:
029: package com.caucho.quercus.lib;
030:
031: import com.caucho.Version;
032: import com.caucho.naming.Jndi;
033: import com.caucho.quercus.QuercusModuleException;
034: import com.caucho.quercus.annotation.NotNull;
035: import com.caucho.quercus.annotation.Optional;
036: import com.caucho.quercus.annotation.ReadOnly;
037: import com.caucho.quercus.env.*;
038: import com.caucho.quercus.module.AbstractQuercusModule;
039: import com.caucho.util.L10N;
040: import com.caucho.vfs.Vfs;
041: import com.caucho.vfs.WriteStream;
042: import com.caucho.webbeans.manager.WebBeansContainer;
043: import com.caucho.webbeans.component.ComponentImpl;
044:
045: import javax.management.MalformedObjectNameException;
046: import javax.management.ObjectName;
047: import javax.naming.Context;
048: import javax.naming.InitialContext;
049: import javax.naming.NamingException;
050: import javax.transaction.UserTransaction;
051: import java.io.IOException;
052: import java.io.UnsupportedEncodingException;
053: import java.util.Hashtable;
054: import java.util.IdentityHashMap;
055: import java.util.Map;
056: import java.util.logging.Level;
057: import java.util.logging.Logger;
058:
059: public class ResinModule extends AbstractQuercusModule {
060: private static final L10N L = new L10N(ResinModule.class);
061:
062: private static final Logger log = Logger
063: .getLogger(ResinModule.class.getName());
064:
065: public final static int XA_STATUS_ACTIVE = 0;
066: public final static int XA_STATUS_MARKED_ROLLBACK = 1;
067: public final static int XA_STATUS_PREPARED = 2;
068: public final static int XA_STATUS_COMMITTED = 3;
069: public final static int XA_STATUS_ROLLEDBACK = 4;
070: public final static int XA_STATUS_UNKNOWN = 5;
071: public final static int XA_STATUS_NO_TRANSACTION = 6;
072: public final static int XA_STATUS_PREPARING = 7;
073: public final static int XA_STATUS_COMMITTING = 8;
074: public final static int XA_STATUS_ROLLING_BACK = 9;
075:
076: /**
077: * Converts a string into its binary representation, according to the
078: * given encoding, if given, or the script encoding if not given.
079: */
080: public static Value string_to_binary(Env env, String string,
081: @Optional
082: String encoding) {
083: if (encoding == null || encoding.length() == 0)
084: encoding = env.getScriptEncoding();
085:
086: try {
087: byte[] bytes = string.getBytes(encoding);
088:
089: return env.createBinaryBuilder(bytes);
090: } catch (UnsupportedEncodingException e) {
091:
092: env.error(e);
093:
094: return BooleanValue.FALSE;
095: }
096: }
097:
098: /**
099: * Returns the matchding webbeans.
100: */
101: public static Object java_bean(String name) {
102: WebBeansContainer webBeans = WebBeansContainer.create();
103:
104: ComponentImpl comp = webBeans.findByName(name);
105:
106: if (comp != null)
107: return comp.get();
108: else
109: return null;
110: }
111:
112: /**
113: * Perform a jndi lookup to retrieve an object.
114: *
115: * @param name a fully qualified name "java:comp/env/foo",
116: * or a short-form "foo".
117:
118: * @return the object, or null if it is not found.
119: */
120: public static Object jndi_lookup(String name) {
121: return Jndi.lookup(name);
122: }
123:
124: /**
125: * Returns the version of the Resin server software.
126: */
127: public static String resin_version() {
128: return Version.FULL_VERSION;
129: }
130:
131: /**
132: * Starts a new distributed transaction.
133: */
134: public static boolean xa_begin(Env env) {
135: try {
136: getUserTransaction().begin();
137:
138: return true;
139: } catch (Exception e) {
140: log.log(Level.FINE, e.getMessage(), e);
141: env.warning(e);
142:
143: return false;
144: }
145: }
146:
147: /**
148: * Commits the current transaction.
149: */
150: public static boolean xa_commit(Env env) {
151: try {
152: getUserTransaction().commit();
153:
154: return true;
155: } catch (Exception e) {
156: log.log(Level.FINE, e.getMessage(), e);
157: env.warning(e);
158:
159: return false;
160: }
161: }
162:
163: /**
164: * Complets the current transaction by rolling it back.
165: */
166: public static boolean xa_rollback(Env env) {
167: try {
168: getUserTransaction().rollback();
169:
170: return true;
171: } catch (Exception e) {
172: log.log(Level.FINE, e.getMessage(), e);
173: env.warning(e);
174:
175: return false;
176: }
177: }
178:
179: /**
180: * Sets the rollback_only status for the current transaction.
181: */
182: public static boolean xa_rollback_only(Env env) {
183: try {
184: getUserTransaction().setRollbackOnly();
185:
186: return true;
187: } catch (Exception e) {
188: log.log(Level.FINE, e.getMessage(), e);
189: env.warning(e);
190:
191: return false;
192: }
193: }
194:
195: /**
196: * Sets the timeout for the current distribued transaction.
197: */
198: public static boolean xa_set_timeout(Env env, int timeoutSeconds) {
199: try {
200: getUserTransaction().setTransactionTimeout(timeoutSeconds);
201:
202: return true;
203: } catch (Exception e) {
204: log.log(Level.FINE, e.getMessage(), e);
205: env.warning(e);
206:
207: return false;
208: }
209: }
210:
211: /**
212: * Returns the JTA status code for the current transation.
213: */
214: public static int xa_status() {
215: try {
216: return getUserTransaction().getStatus();
217: } catch (Exception e) {
218: throw new QuercusModuleException(e);
219: }
220: }
221:
222: /**
223: * Returns the UserTransaction object.
224: */
225: private static UserTransaction getUserTransaction() {
226: try {
227: // XXX: this could be cached, since it's a constant for the
228: // current environment
229:
230: Context ic = new InitialContext();
231:
232: return ((UserTransaction) ic
233: .lookup("java:comp/UserTransaction"));
234: } catch (NamingException e) {
235: throw new QuercusModuleException(e);
236: }
237: }
238:
239: /**
240: * Explode an object name into an array with key value pairs that
241: * correspond to the keys and values in the object name.
242: * The domain is stored in the returned array under the key named ":domain:".
243: */
244: public ArrayValue mbean_explode(String name) {
245: try {
246: ArrayValueImpl exploded = new ArrayValueImpl();
247:
248: if (name == null)
249: name = "";
250:
251: ObjectName objectName = new ObjectName(name);
252:
253: exploded.put(":domain:", objectName.getDomain());
254:
255: Hashtable<String, String> entries = objectName
256: .getKeyPropertyList();
257:
258: for (Map.Entry<String, String> entry : entries.entrySet()) {
259: exploded.put(entry.getKey(), entry.getValue());
260: }
261:
262: return exploded;
263: } catch (MalformedObjectNameException e) {
264: throw new QuercusModuleException(e);
265: }
266: }
267:
268: /**
269: * Implode an array into an object name. The array contains key value pairs
270: * that become key vlaue pairs in the object name. The key with the name
271: * ":domain:" becomes the domain of the object name.
272: */
273: public static String mbean_implode(@NotNull
274: @ReadOnly
275: ArrayValue exploded) {
276: try {
277: if (exploded == null)
278: return null;
279:
280: String domain;
281:
282: Value domainValue = exploded.get(StringValue
283: .create(":domain:"));
284:
285: if (domainValue.isNull())
286: domain = "*";
287: else
288: domain = domainValue.toString();
289:
290: Hashtable<String, String> entries = new Hashtable<String, String>();
291:
292: for (Map.Entry<Value, Value> entry : exploded.entrySet()) {
293: String key = entry.getKey().toString();
294: String value = entry.getValue().toString();
295:
296: if (":domain:".equals(key))
297: continue;
298:
299: entries.put(key, value);
300: }
301:
302: ObjectName objectName;
303:
304: if (entries.isEmpty())
305: objectName = new ObjectName(domain + ":" + "*");
306: else
307: objectName = new ObjectName(domain, entries);
308:
309: return objectName.getCanonicalName();
310: } catch (MalformedObjectNameException e) {
311: throw new QuercusModuleException(e);
312: }
313: }
314:
315: /**
316: * Prints a debug version of the variable
317: *
318: * @param env the quercus calling environment
319: * @param v the variable to print
320: * @return the escaped stringPhp
321: */
322: public static Value resin_var_dump(Env env, @ReadOnly
323: Value v) {
324: try {
325: WriteStream out = Vfs.openWrite("stdout:");
326:
327: if (v != null)
328: v.varDump(env, out, 0,
329: new IdentityHashMap<Value, String>());
330:
331: out.println();
332:
333: out.close();
334:
335: return NullValue.NULL;
336: } catch (IOException e) {
337: throw new QuercusModuleException(e);
338: }
339: }
340: }
|