private static <T> T getParamXPath(
     final Class<T> pClass, final String pXpath, final CompactFragment pBody) throws XmlException {
   // TODO Avoid JAXB where possible, use XMLDeserializer instead
   final boolean string = CharSequence.class.isAssignableFrom(pClass);
   Node match;
   DocumentFragment fragment =
       DomUtil.childrenToDocumentFragment(XMLFragmentStreamReader.from(pBody));
   for (Node n = fragment.getFirstChild(); n != null; n = n.getNextSibling()) {
     match = xpathMatch(n, pXpath);
     if (match != null) {
       if (!string) {
         XmlDeserializer deserializer = pClass.getAnnotation(XmlDeserializer.class);
         if (deserializer != null) {
           try {
             XmlDeserializerFactory<?> factory = deserializer.value().newInstance();
             factory.deserialize(XmlStreaming.newReader(new DOMSource(n)));
           } catch (InstantiationException | IllegalAccessException e) {
             throw new RuntimeException(e);
           }
         } else {
           return JAXB.unmarshal(new DOMSource(match), pClass);
         }
       } else {
         return pClass.cast(nodeToString(match));
       }
     }
   }
   return null;
 }
  /**
   * Given a mix of {@linkplain MockClass mock} and real classes, {@linkplain #setUpMock(Class,
   * Class) sets up} each mock class for the associated real class, and {@linkplain #stubOut stubs
   * out} each specified regular class.
   *
   * @param mockAndRealClasses one or more mock classes and/or regular classes to be stubbed out
   */
  public static void setUpMocksAndStubs(Class<?>... mockAndRealClasses) {
    for (Class<?> mockOrRealClass : mockAndRealClasses) {
      MockClass metadata = mockOrRealClass.getAnnotation(MockClass.class);

      if (metadata != null) {
        new MockClassSetup(mockOrRealClass, metadata).redefineMethods();
      } else {
        new ClassStubbing(mockOrRealClass).stubOut();
      }
    }
  }
 // Ang's suggestion on getting annotation values
 public static String getClassAnnotationValue(
     Class classType, Class annotationType, String attributeName) {
   String value = null;
   Annotation annotation = classType.getAnnotation(annotationType);
   if (annotation != null) {
     try {
       value = (String) annotation.annotationType().getMethod(attributeName).invoke(annotation);
     } catch (Exception ex) {
       System.out.println("Failed loading class annotations");
     }
   }
   return value;
 }
 private JAXBContext newJAXBContext(final Class<?>... pClasses) throws JAXBException {
   Class<?>[] classList;
   final Class<?> clazz = getDeclaringClass();
   final XmlSeeAlso seeAlso = clazz.getAnnotation(XmlSeeAlso.class);
   if ((seeAlso != null) && (seeAlso.value().length > 0)) {
     final Class<?>[] seeAlsoClasses = seeAlso.value();
     classList = new Class<?>[seeAlsoClasses.length + pClasses.length];
     System.arraycopy(seeAlsoClasses, 0, classList, 0, seeAlsoClasses.length);
     System.arraycopy(pClasses, 0, classList, seeAlsoClasses.length, pClasses.length);
   } else {
     classList = pClasses;
   }
   return JAXBContext.newInstance(classList);
 }
Example #5
0
  public static void main(String[] args) throws Exception {
    Class<ClassTest> clazz = ClassTest.class;

    System.out.println("=============================================");
    Constructor[] ctors = clazz.getDeclaredConstructors();
    System.out.println("classTest的全部构造器如下:");
    for (Constructor c : ctors) {
      System.out.println(c);
    }

    System.out.println("=============================================");
    Constructor[] publicCtors = clazz.getConstructors();
    System.out.println("ClassTest的全部public构造器如下:");
    for (Constructor c : publicCtors) {
      System.out.println(c);
    }

    System.out.println("=============================================");
    Method[] mtds = clazz.getMethods();
    System.out.println("ClassTest的全部public方法如下:");
    for (Method md : mtds) {
      System.out.println(md);
    }

    System.out.println("=============================================");
    System.out.println("ClassTest带一个字符串参数的info方法为:" + clazz.getMethod("info", String.class));

    Annotation[] ans = clazz.getAnnotations();
    System.out.println("ClassTest的全部annotation为:");
    for (Annotation an : ans) {
      System.out.println(an);
    }
    System.out.println("该元素上的@SuppressWarnings注释为:" + clazz.getAnnotation(SuppressWarnings.class));

    System.out.println("=============================================");
    Class<?>[] inners = clazz.getDeclaredClasses();
    System.out.println("ClassTest的全部内部类如下:");
    for (Class c : inners) {
      System.out.println(c);
    }

    System.out.println("=============================================");

    Class inClazz = Class.forName("ClassTest$Inner");
    System.out.println("inClazz对应的外部类为:" + inClazz.getDeclaringClass());
    System.out.println("ClassTest的包为:" + clazz.getPackage());
    System.out.println("ClassTest的父类:" + clazz.getSuperclass());
  }
Example #6
0
 public static <T extends Annotation> T digAnnotation(
     Class<?> target, Class<T> annotationType, List<Class<? extends Annotation>> visited) {
   T result = target.getAnnotation(annotationType);
   if (result == null) {
     for (Annotation a : target.getAnnotations()) {
       if (!visited.contains(a.annotationType())) {
         visited.add(a.annotationType());
         result = digAnnotation(a.annotationType(), annotationType, visited);
         if (result != null) {
           return result;
         }
       }
     }
   }
   return result;
 }
Example #7
0
  private String resolveTypeDiscriminator(final Class<?> persistentType) {
    final List<String> discrimintators = new ArrayList<String>();
    TypeDiscriminator td = persistentType.getAnnotation(TypeDiscriminator.class);
    if (td != null) {
      if (td.value().length() == 0) {
        throw new ViewGenerationException(
            String.format(
                "@TypeDiscriminator declared on type level must specify custom discriminator condition",
                persistentType));
      }
      if (hasTypeDiscriminatorFieldOrMethod(persistentType)) {
        throw new ViewGenerationException(
            String.format(
                "@TypeDiscriminator declared on type level may not be combined with @TypeDiscriminator in fields or on methods",
                persistentType));
      }
      return td.value();
    }

    eachField(
        persistentType,
        new Predicate<Field>() {
          public boolean apply(Field input) {
            if (hasAnnotation(input, TypeDiscriminator.class)) {
              discrimintators.add("doc." + input.getName());
            }
            return false;
          }
        });

    eachMethod(
        persistentType,
        new Predicate<Method>() {
          public boolean apply(Method input) {
            if (hasAnnotation(input, TypeDiscriminator.class)) {
              discrimintators.add("doc." + firstCharToLowerCase(input.getName().substring(3)));
            }
            return true;
          }
        });
    return Joiner.join(discrimintators, " && ");
  }
  @SuppressWarnings("unchecked")
  LDAPObjectHandler(final Class<T> type) throws LDAPPersistException {
    this.type = type;

    final Class<? super T> superclassType = type.getSuperclass();
    if (superclassType == null) {
      superclassHandler = null;
    } else {
      final LDAPObject superclassAnnotation = superclassType.getAnnotation(LDAPObject.class);
      if (superclassAnnotation == null) {
        superclassHandler = null;
      } else {
        superclassHandler = new LDAPObjectHandler(superclassType);
      }
    }

    final TreeMap<String, FieldInfo> fields = new TreeMap<String, FieldInfo>();
    final TreeMap<String, GetterInfo> getters = new TreeMap<String, GetterInfo>();
    final TreeMap<String, SetterInfo> setters = new TreeMap<String, SetterInfo>();

    ldapObject = type.getAnnotation(LDAPObject.class);
    if (ldapObject == null) {
      throw new LDAPPersistException(ERR_OBJECT_HANDLER_OBJECT_NOT_ANNOTATED.get(type.getName()));
    }

    final LinkedHashMap<String, String> objectClasses = new LinkedHashMap<String, String>(10);

    final String oc = ldapObject.structuralClass();
    if (oc.length() == 0) {
      structuralClass = getUnqualifiedClassName(type);
    } else {
      structuralClass = oc;
    }

    final StringBuilder invalidReason = new StringBuilder();
    if (PersistUtils.isValidLDAPName(structuralClass, invalidReason)) {
      objectClasses.put(toLowerCase(structuralClass), structuralClass);
    } else {
      throw new LDAPPersistException(
          ERR_OBJECT_HANDLER_INVALID_STRUCTURAL_CLASS.get(
              type.getName(), structuralClass, invalidReason.toString()));
    }

    auxiliaryClasses = ldapObject.auxiliaryClass();
    for (final String auxiliaryClass : auxiliaryClasses) {
      if (PersistUtils.isValidLDAPName(auxiliaryClass, invalidReason)) {
        objectClasses.put(toLowerCase(auxiliaryClass), auxiliaryClass);
      } else {
        throw new LDAPPersistException(
            ERR_OBJECT_HANDLER_INVALID_AUXILIARY_CLASS.get(
                type.getName(), auxiliaryClass, invalidReason.toString()));
      }
    }

    superiorClasses = ldapObject.superiorClass();
    for (final String superiorClass : superiorClasses) {
      if (PersistUtils.isValidLDAPName(superiorClass, invalidReason)) {
        objectClasses.put(toLowerCase(superiorClass), superiorClass);
      } else {
        throw new LDAPPersistException(
            ERR_OBJECT_HANDLER_INVALID_SUPERIOR_CLASS.get(
                type.getName(), superiorClass, invalidReason.toString()));
      }
    }

    if (superclassHandler != null) {
      for (final String s : superclassHandler.objectClassAttribute.getValues()) {
        objectClasses.put(toLowerCase(s), s);
      }
    }

    objectClassAttribute = new Attribute("objectClass", objectClasses.values());

    final String parentDNStr = ldapObject.defaultParentDN();
    try {
      defaultParentDN = new DN(parentDNStr);
    } catch (LDAPException le) {
      throw new LDAPPersistException(
          ERR_OBJECT_HANDLER_INVALID_DEFAULT_PARENT.get(
              type.getName(), parentDNStr, le.getMessage()),
          le);
    }

    final String postDecodeMethodName = ldapObject.postDecodeMethod();
    if (postDecodeMethodName.length() > 0) {
      try {
        postDecodeMethod = type.getDeclaredMethod(postDecodeMethodName);
        postDecodeMethod.setAccessible(true);
      } catch (Exception e) {
        debugException(e);
        throw new LDAPPersistException(
            ERR_OBJECT_HANDLER_INVALID_POST_DECODE_METHOD.get(
                type.getName(), postDecodeMethodName, getExceptionMessage(e)),
            e);
      }
    } else {
      postDecodeMethod = null;
    }

    final String postEncodeMethodName = ldapObject.postEncodeMethod();
    if (postEncodeMethodName.length() > 0) {
      try {
        postEncodeMethod = type.getDeclaredMethod(postEncodeMethodName, Entry.class);
        postEncodeMethod.setAccessible(true);
      } catch (Exception e) {
        debugException(e);
        throw new LDAPPersistException(
            ERR_OBJECT_HANDLER_INVALID_POST_ENCODE_METHOD.get(
                type.getName(), postEncodeMethodName, getExceptionMessage(e)),
            e);
      }
    } else {
      postEncodeMethod = null;
    }

    try {
      constructor = type.getDeclaredConstructor();
      constructor.setAccessible(true);
    } catch (Exception e) {
      debugException(e);
      throw new LDAPPersistException(
          ERR_OBJECT_HANDLER_NO_DEFAULT_CONSTRUCTOR.get(type.getName()), e);
    }

    Field tmpDNField = null;
    Field tmpEntryField = null;
    final LinkedList<FieldInfo> tmpRFilterFields = new LinkedList<FieldInfo>();
    final LinkedList<FieldInfo> tmpAAFilterFields = new LinkedList<FieldInfo>();
    final LinkedList<FieldInfo> tmpCAFilterFields = new LinkedList<FieldInfo>();
    final LinkedList<FieldInfo> tmpRDNFields = new LinkedList<FieldInfo>();
    for (final Field f : type.getDeclaredFields()) {
      final LDAPField fieldAnnotation = f.getAnnotation(LDAPField.class);
      final LDAPDNField dnFieldAnnotation = f.getAnnotation(LDAPDNField.class);
      final LDAPEntryField entryFieldAnnotation = f.getAnnotation(LDAPEntryField.class);

      if (fieldAnnotation != null) {
        f.setAccessible(true);

        final FieldInfo fieldInfo = new FieldInfo(f, type);
        final String attrName = toLowerCase(fieldInfo.getAttributeName());
        if (fields.containsKey(attrName)) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_ATTR_CONFLICT.get(type.getName(), fieldInfo.getAttributeName()));
        } else {
          fields.put(attrName, fieldInfo);
        }

        switch (fieldInfo.getFilterUsage()) {
          case REQUIRED:
            tmpRFilterFields.add(fieldInfo);
            break;
          case ALWAYS_ALLOWED:
            tmpAAFilterFields.add(fieldInfo);
            break;
          case CONDITIONALLY_ALLOWED:
            tmpCAFilterFields.add(fieldInfo);
            break;
          case EXCLUDED:
          default:
            break;
        }

        if (fieldInfo.includeInRDN()) {
          tmpRDNFields.add(fieldInfo);
        }
      }

      if (dnFieldAnnotation != null) {
        f.setAccessible(true);

        if (fieldAnnotation != null) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_CONFLICTING_FIELD_ANNOTATIONS.get(
                  type.getName(), "LDAPField", "LDAPDNField", f.getName()));
        }

        if (tmpDNField != null) {
          throw new LDAPPersistException(ERR_OBJECT_HANDLER_MULTIPLE_DN_FIELDS.get(type.getName()));
        }

        final int modifiers = f.getModifiers();
        if (Modifier.isFinal(modifiers)) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_DN_FIELD_FINAL.get(f.getName(), type.getName()));
        } else if (Modifier.isStatic(modifiers)) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_DN_FIELD_STATIC.get(f.getName(), type.getName()));
        }

        final Class<?> fieldType = f.getType();
        if (fieldType.equals(String.class)) {
          tmpDNField = f;
        } else {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_INVALID_DN_FIELD_TYPE.get(
                  type.getName(), f.getName(), fieldType.getName()));
        }
      }

      if (entryFieldAnnotation != null) {
        f.setAccessible(true);

        if (fieldAnnotation != null) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_CONFLICTING_FIELD_ANNOTATIONS.get(
                  type.getName(), "LDAPField", "LDAPEntryField", f.getName()));
        }

        if (tmpEntryField != null) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_MULTIPLE_ENTRY_FIELDS.get(type.getName()));
        }

        final int modifiers = f.getModifiers();
        if (Modifier.isFinal(modifiers)) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_ENTRY_FIELD_FINAL.get(f.getName(), type.getName()));
        } else if (Modifier.isStatic(modifiers)) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_ENTRY_FIELD_STATIC.get(f.getName(), type.getName()));
        }

        final Class<?> fieldType = f.getType();
        if (fieldType.equals(ReadOnlyEntry.class)) {
          tmpEntryField = f;
        } else {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_INVALID_ENTRY_FIELD_TYPE.get(
                  type.getName(), f.getName(), fieldType.getName()));
        }
      }
    }

    dnField = tmpDNField;
    entryField = tmpEntryField;
    requiredFilterFields = Collections.unmodifiableList(tmpRFilterFields);
    alwaysAllowedFilterFields = Collections.unmodifiableList(tmpAAFilterFields);
    conditionallyAllowedFilterFields = Collections.unmodifiableList(tmpCAFilterFields);
    rdnFields = Collections.unmodifiableList(tmpRDNFields);

    final LinkedList<GetterInfo> tmpRFilterGetters = new LinkedList<GetterInfo>();
    final LinkedList<GetterInfo> tmpAAFilterGetters = new LinkedList<GetterInfo>();
    final LinkedList<GetterInfo> tmpCAFilterGetters = new LinkedList<GetterInfo>();
    final LinkedList<GetterInfo> tmpRDNGetters = new LinkedList<GetterInfo>();
    for (final Method m : type.getDeclaredMethods()) {
      final LDAPGetter getter = m.getAnnotation(LDAPGetter.class);
      final LDAPSetter setter = m.getAnnotation(LDAPSetter.class);

      if (getter != null) {
        m.setAccessible(true);

        if (setter != null) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_CONFLICTING_METHOD_ANNOTATIONS.get(
                  type.getName(), "LDAPGetter", "LDAPSetter", m.getName()));
        }

        final GetterInfo methodInfo = new GetterInfo(m, type);
        final String attrName = toLowerCase(methodInfo.getAttributeName());
        if (fields.containsKey(attrName) || getters.containsKey(attrName)) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_ATTR_CONFLICT.get(type.getName(), methodInfo.getAttributeName()));
        } else {
          getters.put(attrName, methodInfo);
        }

        switch (methodInfo.getFilterUsage()) {
          case REQUIRED:
            tmpRFilterGetters.add(methodInfo);
            break;
          case ALWAYS_ALLOWED:
            tmpAAFilterGetters.add(methodInfo);
            break;
          case CONDITIONALLY_ALLOWED:
            tmpCAFilterGetters.add(methodInfo);
            break;
          case EXCLUDED:
          default:
            // No action required.
            break;
        }

        if (methodInfo.includeInRDN()) {
          tmpRDNGetters.add(methodInfo);
        }
      }

      if (setter != null) {
        m.setAccessible(true);

        final SetterInfo methodInfo = new SetterInfo(m, type);
        final String attrName = toLowerCase(methodInfo.getAttributeName());
        if (fields.containsKey(attrName) || setters.containsKey(attrName)) {
          throw new LDAPPersistException(
              ERR_OBJECT_HANDLER_ATTR_CONFLICT.get(type.getName(), methodInfo.getAttributeName()));
        } else {
          setters.put(attrName, methodInfo);
        }
      }
    }

    requiredFilterGetters = Collections.unmodifiableList(tmpRFilterGetters);
    alwaysAllowedFilterGetters = Collections.unmodifiableList(tmpAAFilterGetters);
    conditionallyAllowedFilterGetters = Collections.unmodifiableList(tmpCAFilterGetters);

    rdnGetters = Collections.unmodifiableList(tmpRDNGetters);
    if (rdnFields.isEmpty() && rdnGetters.isEmpty()) {
      throw new LDAPPersistException(ERR_OBJECT_HANDLER_NO_RDN_DEFINED.get(type.getName()));
    }

    fieldMap = Collections.unmodifiableMap(fields);
    getterMap = Collections.unmodifiableMap(getters);
    setterMap = Collections.unmodifiableMap(setters);

    final TreeSet<String> attrSet = new TreeSet<String>();
    final TreeSet<String> lazySet = new TreeSet<String>();
    if (ldapObject.requestAllAttributes()) {
      attrSet.add("*");
      attrSet.add("+");
    } else {
      for (final FieldInfo i : fields.values()) {
        if (i.lazilyLoad()) {
          lazySet.add(i.getAttributeName());
        } else {
          attrSet.add(i.getAttributeName());
        }
      }

      for (final SetterInfo i : setters.values()) {
        attrSet.add(i.getAttributeName());
      }
    }
    attributesToRequest = new String[attrSet.size()];
    attrSet.toArray(attributesToRequest);

    lazilyLoadedAttributes = new String[lazySet.size()];
    lazySet.toArray(lazilyLoadedAttributes);
  }
  private Object getParam(
      final Class<?> pClass,
      final String pName,
      final ParamType pType,
      final String pXpath,
      final HttpMessage pMessage)
      throws XmlException {
    Object result = null;
    switch (pType) {
      case GET:
        result = getParamGet(pName, pMessage);
        break;
      case POST:
        result = getParamPost(pName, pMessage);
        break;
      case QUERY:
        result = getParamGet(pName, pMessage);
        if (result == null) {
          result = getParamPost(pName, pMessage);
        }
        break;
      case VAR:
        result = mPathParams.get(pName);
        break;
      case XPATH:
        result = getParamXPath(pClass, pXpath, pMessage.getBody());
        break;
      case BODY:
        result = getBody(pClass, pMessage);
        break;
      case ATTACHMENT:
        result = getAttachment(pClass, pName, pMessage);
        break;
      case PRINCIPAL:
        {
          final Principal principal = pMessage.getUserPrincipal();
          if (pClass.isAssignableFrom(String.class)) {
            result = principal.getName();
          } else {
            result = principal;
          }
          break;
        }
    }
    // XXX generizice this and share the same approach to unmarshalling in ALL code
    // TODO support collection/list parameters
    if ((result != null) && (!pClass.isInstance(result))) {
      if ((Types.isPrimitive(pClass) || (Types.isPrimitiveWrapper(pClass)))
          && (result instanceof String)) {
        try {
          result = Types.parsePrimitive(pClass, ((String) result));
        } catch (NumberFormatException e) {
          throw new HttpResponseException(
              HttpServletResponse.SC_BAD_REQUEST, "The argument given is invalid", e);
        }
      } else if (Enum.class.isAssignableFrom(pClass)) {
        @SuppressWarnings({"rawtypes"})
        final Class clazz = pClass;
        @SuppressWarnings("unchecked")
        final Enum<?> tmpResult = Enum.valueOf(clazz, result.toString());
        result = tmpResult;
      } else if (result instanceof Node) {
        XmlDeserializer factory = pClass.getAnnotation(XmlDeserializer.class);
        if (factory != null) {
          try {
            result =
                factory
                    .value()
                    .newInstance()
                    .deserialize(XmlStreaming.newReader(new DOMSource((Node) result)));
          } catch (IllegalAccessException | InstantiationException e) {
            throw new XmlException(e);
          }
        } else {
          result = JAXB.unmarshal(new DOMSource((Node) result), pClass);
        }
      } else {
        final String s = result.toString();
        // Only wrap when we don't start with <
        final char[] requestBody =
            (s.startsWith("<") ? s : "<wrapper>" + s + "</wrapper>").toCharArray();
        if (requestBody.length > 0) {
          result = JAXB.unmarshal(new CharArrayReader(requestBody), pClass);
        } else {
          result = null;
        }
      }
    }

    return result;
  }
Example #10
0
 protected void loadHttpServlet(final AnyValue conf, final ClassFilter<? extends Servlet> filter)
     throws Exception {
   final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
   final String prefix = conf == null ? "" : conf.getValue("path", "");
   final String threadName = "[" + Thread.currentThread().getName() + "] ";
   List<FilterEntry<? extends Servlet>> list = new ArrayList(filter.getFilterEntrys());
   list.sort(
       (FilterEntry<? extends Servlet> o1,
           FilterEntry<? extends Servlet>
               o2) -> { // 必须保证WebSocketServlet优先加载, 因为要确保其他的HttpServlet可以注入本地模式的WebSocketNode
         boolean ws1 = WebSocketServlet.class.isAssignableFrom(o1.getType());
         boolean ws2 = WebSocketServlet.class.isAssignableFrom(o2.getType());
         if (ws1 == ws2) return o1.getType().getName().compareTo(o2.getType().getName());
         return ws1 ? -1 : 1;
       });
   final List<AbstractMap.SimpleEntry<String, String[]>> ss =
       sb == null ? null : new ArrayList<>();
   for (FilterEntry<? extends Servlet> en : list) {
     Class<HttpServlet> clazz = (Class<HttpServlet>) en.getType();
     if (Modifier.isAbstract(clazz.getModifiers())) continue;
     WebServlet ws = clazz.getAnnotation(WebServlet.class);
     if (ws == null || ws.value().length == 0) continue;
     final HttpServlet servlet = clazz.newInstance();
     resourceFactory.inject(servlet, this);
     final String[] mappings = ws.value();
     String pref = ws.repair() ? prefix : "";
     DefaultAnyValue servletConf = (DefaultAnyValue) en.getProperty();
     WebInitParam[] webparams = ws.initParams();
     if (webparams.length > 0) {
       if (servletConf == null) servletConf = new DefaultAnyValue();
       for (WebInitParam webparam : webparams) {
         servletConf.addValue(webparam.name(), webparam.value());
       }
     }
     this.httpServer.addHttpServlet(servlet, pref, servletConf, mappings);
     if (ss != null) {
       for (int i = 0; i < mappings.length; i++) {
         mappings[i] = pref + mappings[i];
       }
       ss.add(new AbstractMap.SimpleEntry<>(clazz.getName(), mappings));
     }
   }
   if (ss != null) {
     Collections.sort(
         ss,
         (AbstractMap.SimpleEntry<String, String[]> o1,
             AbstractMap.SimpleEntry<String, String[]> o2) -> o1.getKey().compareTo(o2.getKey()));
     int max = 0;
     for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
       if (as.getKey().length() > max) max = as.getKey().length();
     }
     for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
       sb.append(threadName).append(" Loaded ").append(as.getKey());
       for (int i = 0; i < max - as.getKey().length(); i++) {
         sb.append(' ');
       }
       sb.append("  mapping to  ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR);
     }
   }
   if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
 }