/**
  * 实际删除私有属性,如果是窗口共有的portal属性,只是在本窗口中做删除标志,其他窗口还能正常获取
  *
  * @param name Name of the attribute to remove
  */
 public void removeAttribute(String name) {
   if (name == null) {
     throw new NullPointerException("don't set a NULL named attribute");
   }
   synchronized (mutex) {
     window.remove(name);
     if (deleteAttributes == null) {
       deleteAttributes = new HashSet<String>(4);
       deleteAttributes.add(name);
     }
   }
 }
 /**
  * 返回这个窗口的私有属性或portal主控请求对象的共同属性
  *
  * @param name Name of the attribute to retrieve
  */
 public Object getAttribute(String name) {
   Object value = null;
   synchronized (mutex) {
     if (deleteAttributes != null && deleteAttributes.contains(name)) {
       return null;
     }
     value = window.get(name);
     if (value == null) {
       value = super.getAttribute(name);
     }
   }
   return value;
 }
 /**
  * 设置窗口私有属性
  *
  * @param name Name of the attribute to set
  * @param value Value of the attribute to set
  */
 public void setAttribute(String name, Object value) {
   if (name == null) {
     throw new NullPointerException("don't set a NULL named attribute");
   }
   if (value == null) {
     removeAttribute(name);
     return;
   }
   synchronized (mutex) {
     window.set(name, value);
     if (deleteAttributes != null) {
       deleteAttributes.remove(name);
     }
   }
 }
 /** 返回这个窗口的私有属性名加portal主控请求对象共同属性的属性名 */
 @SuppressWarnings("unchecked")
 public Enumeration getAttributeNames() {
   HashSet<String> keys;
   synchronized (mutex) {
     keys = new HashSet<String>(window.getAttributes().keySet());
     Enumeration<String> names = super.getAttributeNames();
     while (names.hasMoreElements()) {
       String name = (String) names.nextElement();
       if (deleteAttributes == null || !deleteAttributes.contains(name)) {
         keys.add(name);
       }
     }
   }
   return new Enumerator(keys);
 }
 @Override
 public HttpSession getSession(boolean create) {
   HttpSession session = super.getSession(false);
   if (session != null) {
     return session;
   }
   if (create) {
     if (window.getContainer().getInvocation().getResponse().isCommitted()) {
       session =
           new SessionAfterCommitted(
               new IllegalStateException(
                   "Cannot create a session after the response has been committed"));
     } else {
       try {
         session = super.getSession(true);
       } catch (IllegalStateException e) {
         session = new SessionAfterCommitted(e);
       }
     }
   }
   return session;
 }
 public Map<String, Object> getPrivateAttributes() {
   return window.getAttributes();
 }