⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uiengineimpl.java

📁 ZK 基础介绍 功能操作 模块 结合数据库操作
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
			doDeactivate(exec);			if (monitor != null) {				try {					monitor.afterUpdate(desktop);				} catch (Throwable ex) {					log.error(ex);				}			}			return doneReqIds;		}	}	/** Handles each error. The erros will be queued to the errs list	 * and processed later by {@link #visualizeErrors}.	 */	private static final	void handleError(Throwable ex, UiVisualizer uv, List errs) {		final Throwable err = ex;		final Throwable t = Exceptions.findCause(ex, Expectable.class);		if (t == null) {			log.realCauseBriefly(ex);		} else {			ex = t;			if (log.debugable()) log.debug(Exceptions.getRealCause(ex));		}		if (ex instanceof WrongValueException) {			WrongValueException wve = (WrongValueException)ex;			final Component comp = wve.getComponent();			if (comp != null) {				wve = ((ComponentCtrl)comp).onWrongValue(wve);				if (wve != null)					uv.addResponse("wrongValue",						new AuWrongValue(comp, Exceptions.getMessage(wve)));				return;			}		}		errs.add(err);	}	/** Post-process the errors to represent them to the user.	 * Note: errs must be non-empty	 */	private final	void visualizeErrors(Execution exec, UiVisualizer uv, List errs) {		final StringBuffer sb = new StringBuffer(128);		for (Iterator it = errs.iterator(); it.hasNext();) {			final Throwable t = (Throwable)it.next();			if (sb.length() > 0) sb.append('\n');			sb.append(Exceptions.getMessage(t));		}		final String msg = sb.toString();		final Throwable err = (Throwable)errs.get(0);		final Desktop desktop = exec.getDesktop();		final Configuration config = desktop.getWebApp().getConfiguration();		final String location = config.getErrorPage(desktop.getDeviceType(), err);		if (location != null) {			try {				exec.setAttribute("javax.servlet.error.message", msg);				exec.setAttribute("javax.servlet.error.exception", err);				exec.setAttribute("javax.servlet.error.exception_type", err.getClass());				exec.setAttribute("javax.servlet.error.status_code", new Integer(500));				//Future: consider to go thru UiFactory for the richlet				//for the error page.				//Challenge: how to call UiFactory.isRichlet				final Richlet richlet = config.getRichletByPath(location);				if (richlet != null)					richlet.service(getCurrentPage(exec));				else					exec.createComponents(location, null, null);				//process pending events				//the execution is aborted if an exception is thrown				Event event = nextEvent(uv);				do {					for (; event != null; event = nextEvent(uv)) {						try {							process(desktop, event);						} catch (SuspendNotAllowedException ex) {							//ignore it (possible and reasonable)						}					}					resumeAll(desktop, uv, null);				} while ((event = nextEvent(uv)) != null);				return; //done			} catch (Throwable ex) {				log.realCause("Unable to generate custom error page, "+location, ex);			}		}		uv.addResponse(null, new AuAlert(msg)); //default handling	}	private static final Page getCurrentPage(Execution exec) {		final Page page = ((ExecutionCtrl)exec).getCurrentPage();		return page != null ? page:			(Page)exec.getDesktop().getPages().iterator().next();	}	/** Processing the request and stores result into UiVisualizer.	 * @param everError whether any error ever occured before processing this	 * request.	 */	private void process(Execution exec, AuRequest request, boolean everError) {//		if (log.finable()) log.finer("Processing request: "+request);		final ExecutionCtrl execCtrl = (ExecutionCtrl)exec;		execCtrl.setCurrentPage(request.getPage());		request.getCommand().process(request, everError);	}	/** Processing the event and stores result into UiVisualizer. */	private void process(Desktop desktop, Event event) {//		if (log.finable()) log.finer("Processing event: "+event);		final Component comp = event.getTarget();		if (comp != null) {			processEvent(desktop, comp, event);		} else {			//since an event might change the page/desktop/component relation,			//we copy roots first			final List roots = new LinkedList();			for (Iterator it = desktop.getPages().iterator(); it.hasNext();) {				roots.addAll(((Page)it.next()).getRoots());			}			for (Iterator it = roots.iterator(); it.hasNext();) {				final Component c = (Component)it.next();				if (c.getPage() != null) //might be removed, so check first					processEvent(desktop, c, event);			}		}	}	public void wait(Object mutex)	throws InterruptedException, SuspendNotAllowedException {		if (mutex == null)			throw new IllegalArgumentException("null mutex");		final Thread thd = Thread.currentThread();		if (!(thd instanceof EventProcessingThreadImpl))			throw new UiException("This method can be called only in an event listener, not in paging loading.");//		if (log.finerable()) log.finer("Suspend "+thd+" on "+mutex);		final EventProcessingThreadImpl evtthd = (EventProcessingThreadImpl)thd;		evtthd.newEventThreadSuspends(mutex);			//it may throw an exception, so process it before updating _suspended		final Execution exec = Executions.getCurrent();		final Desktop desktop = exec.getDesktop();		incSuspended();		Map map;		synchronized (_suspended) {			map = (Map)_suspended.get(desktop);			if (map == null)				_suspended.put(desktop, map = new IdentityHashMap(3));					//note: we have to use IdentityHashMap because user might					//use Integer or so as mutex		}		synchronized (map) {			List list = (List)map.get(mutex);			if (list == null)				map.put(mutex, list = new LinkedList());			list.add(evtthd);		}		try {			EventProcessingThreadImpl.doSuspend(mutex);		} catch (Throwable ex) {			//error recover			synchronized (map) {				final List list = (List)map.get(mutex);				if (list != null) {					list.remove(evtthd);					if (list.isEmpty()) map.remove(mutex);				}			}			if (ex instanceof InterruptedException)				throw (InterruptedException)ex;			throw UiException.Aide.wrap(ex, "Unable to suspend "+evtthd);		} finally {			decSuspended();		}	}	private void incSuspended() {		final int v = _wapp.getConfiguration().getMaxSuspendedThreads();		synchronized (this) {			if (v >= 0 && _suspCnt >= v)				throw new SuspendNotAllowedException(MZk.TOO_MANY_SUSPENDED);			++_suspCnt;		}	}	private void decSuspended() {		synchronized (this) {			--_suspCnt;		}	}	public void notify(Object mutex) {		notify(Executions.getCurrent().getDesktop(), mutex);	}	public void notify(Desktop desktop, Object mutex) {		if (desktop == null || mutex == null)			throw new IllegalArgumentException("desktop and mutex cannot be null");		final Map map;		synchronized (_suspended) {			map = (Map)_suspended.get(desktop);		}		if (map == null) return; //nothing to notify		final EventProcessingThreadImpl evtthd;		synchronized (map) {			final List list = (List)map.get(mutex);			if (list == null) return; //nothing to notify			//Note: list is never empty			evtthd = (EventProcessingThreadImpl)list.remove(0);			if (list.isEmpty()) map.remove(mutex); //clean up		}		addResumed(desktop, evtthd);	}	public void notifyAll(Object mutex) {		final Execution exec = Executions.getCurrent();		if (exec == null)			throw new UiException("resume can be called only in processing a request");		notifyAll(exec.getDesktop(), mutex);	}	public void notifyAll(Desktop desktop, Object mutex) {		if (desktop == null || mutex == null)			throw new IllegalArgumentException("desktop and mutex cannot be null");		final Map map;		synchronized (_suspended) {			map = (Map)_suspended.get(desktop);		}		if (map == null) return; //nothing to notify		final List list;		synchronized (map) {			list = (List)map.remove(mutex);			if (list == null) return; //nothing to notify		}		for (Iterator it = list.iterator(); it.hasNext();)			addResumed(desktop, (EventProcessingThreadImpl)it.next());	}	/** Adds to _resumed */	private void addResumed(Desktop desktop, EventProcessingThreadImpl evtthd) {//		if (log.finerable()) log.finer("Ready to resume "+evtthd);		List list;		synchronized (_resumed) {			list = (List)_resumed.get(desktop);			if (list == null)				_resumed.put(desktop, list = new LinkedList());		}		synchronized (list) {			list.add(evtthd);		}	}	/** Does the real resume.	 * <p>Note 1: the current thread will wait until the resumed threads, if any, complete	 * <p>Note 2: {@link #resume} only puts a thread into a resume queue in execution.	 */	private void resumeAll(Desktop desktop, UiVisualizer uv, List errs) {		//We have to loop because a resumed thread might resume others		for (;;) {			final List list;			synchronized (_resumed) {				list = (List)_resumed.remove(desktop);				if (list == null) return; //nothing to resume; done			}			synchronized (list) {				for (Iterator it = list.iterator(); it.hasNext();) {					final EventProcessingThreadImpl evtthd =						(EventProcessingThreadImpl)it.next();					if (uv.isAborting()) {						evtthd.ceaseSilently("Resume aborted");					} else {//						if (log.finerable()) log.finer("Resume "+evtthd);						try {							if (evtthd.doResume()) //wait it complete or suspend again								recycleEventThread(evtthd); //completed						} catch (Throwable ex) {							recycleEventThread(evtthd);							if (errs == null) {								log.error("Unable to resume "+evtthd, ex);								throw UiException.Aide.wrap(ex);							}							handleError(ex, uv, errs);						}					}				}			}		}	}	/** Process an event. */	private void processEvent(Desktop desktop, Component comp, Event event) {		final Configuration config = desktop.getWebApp().getConfiguration();		if (config.isEventThreadEnabled()) {			EventProcessingThreadImpl evtthd = null;			synchronized (_idles) {				if (!_idles.isEmpty())					evtthd = (EventProcessingThreadImpl)_idles.remove(0);			}			if (evtthd == null)				evtthd = new EventProcessingThreadImpl();			try {				if (evtthd.processEvent(desktop, comp, event))					recycleEventThread(evtthd);			} catch (Throwable ex) {				recycleEventThread(evtthd);				throw UiException.Aide.wrap(ex);			}		} else { //event thread disabled			//Note: we don't need to call proc.setup() and cleanup(),			//since they are in the same thread			EventProcessor proc = new EventProcessor(desktop, comp, event);				//Note: it also checks the correctness			List cleanups = null, errs = null;			try {				final List inits = config.newEventThreadInits(comp, event);				EventProcessor.inEventListener(true);				if (config.invokeEventThreadInits(inits, comp, event)) //false measn ignore					proc.process();			} catch (Throwable ex) {				errs = new LinkedList();				errs.add(ex);				cleanups = config.newEventThreadCleanups(comp, event, errs);				throw UiException.Aide.wrap(ex);			} finally {				EventProcessor.inEventListener(false);				if (errs == null) //not cleanup yet					cleanups = config.newEventThreadCleanups(comp, event, null);				config.invokeEventThreadCompletes(cleanups, comp, event, errs);			}		}	}	private void recycleEventThread(EventProcessingThreadImpl evtthd) {		if (!evtthd.isCeased()) {			if (evtthd.isIdle()) {				final int max = _wapp.getConfiguration().getMaxSpareThreads();				synchronized (_idles) {					if (max < 0 || _idles.size() < max) {						_idles.add(evtthd); //return to pool						return; //done					}				}			}			evtthd.ceaseSilently("Recycled");		}	}	//-- Generate output from a response --//	/** Output the next response sequence ID.	 */	private static void responseSequenceId(Desktop desktop, Writer out)	throws IOException {		out.write("\n<sid>");		out.write(Integer.toString(			((DesktopCtrl)desktop).getResponseSequence(true)));		out.write("</sid>");	}	public void response(AuResponse response, Writer out)	throws IOException {		out.write("\n<r><c>");		out.write(response.getCommand());		out.write("</c>");		final String[] data = response.getData();		if (data != null) {			for (int j = 0; j < data.length; ++j) {				out.write("\n<d>");				encodeXML(data[j], out);				out.write("</d>");			}		}		out.write("\n</r>");	}	public void response(List responses, Writer out)	throws IOException {		for (Iterator it = responses.iterator(); it.hasNext();)			response((AuResponse)it.next(), out);	}	private static void encodeXML(String data, Writer out)	throws IOException {		if (data == null || data.length() == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -