/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.wink.common.internal.type; /** * Type that represents Java Collection types (Lists, Sets). */ public final class CollectionType extends TypeBase { /** * Type of elements in collection */ final JavaType _elementType; /* /********************************************************** /* Life-cycle /********************************************************** */ private CollectionType(Class<?> collT, JavaType elemT) { super(collT, elemT.hashCode()); _elementType = elemT; } @Override protected JavaType _narrow(Class<?> subclass) { return new CollectionType(subclass, _elementType); } @Override public JavaType narrowContentsBy(Class<?> contentClass) { // Can do a quick check first: if (contentClass == _elementType.getRawClass()) { return this; } JavaType newElementType = _elementType.narrowBy(contentClass); return new CollectionType(_class, newElementType).copyHandlers(this); } public static CollectionType construct(Class<?> rawType, JavaType elemT) { // nominally component types will be just Object.class return new CollectionType(rawType, elemT); } // Since 1.7: @Override public CollectionType withTypeHandler(Object h) { CollectionType newInstance = new CollectionType(_class, _elementType); newInstance._typeHandler = h; return newInstance; } // Since 1.7: @Override public CollectionType withContentTypeHandler(Object h) { return new CollectionType(_class, _elementType.withTypeHandler(h)); } @Override protected String buildCanonicalName() { StringBuilder sb = new StringBuilder(); sb.append(_class.getName()); if (_elementType != null) { sb.append('<'); sb.append(_elementType.toCanonical()); sb.append('>'); } return sb.toString(); } /* /********************************************************** /* Public API /********************************************************** */ @Override public JavaType getContentType() { return _elementType; } @Override public int containedTypeCount() { return 1; } @Override public JavaType containedType(int index) { return (index == 0) ? _elementType : null; } /** * Not sure if we should count on this, but type names * for core interfaces use "E" for element type */ @Override public String containedTypeName(int index) { if (index == 0) return "E"; return null; } @Override public StringBuilder getErasedSignature(StringBuilder sb) { return _classSignature(_class, sb, true); } @Override public StringBuilder getGenericSignature(StringBuilder sb) { _classSignature(_class, sb, false); sb.append('<'); _elementType.getGenericSignature(sb); sb.append(">;"); return sb; } /* /********************************************************** /* Extended API /********************************************************** */ @Override public boolean isContainerType() { return true; } /* /********************************************************** /* Standard methods /********************************************************** */ @Override public String toString() { return "[collection type; class " + _class.getName() + ", contains " + _elementType + "]"; } @Override public boolean equals(Object o) { if (o == this) return true; if (o == null) return false; if (o.getClass() != getClass()) return false; CollectionType other = (CollectionType)o; return (_class == other._class) && _elementType.equals(other._elementType); } }