private T2Reference getNameForObject()

in taverna-reference-impl/src/main/java/org/apache/taverna/reference/impl/ReferenceServiceImpl.java [147:343]


	private T2Reference getNameForObject(Object o, int currentDepth,
			boolean useConverterSPI, ReferenceContext context)
			throws ReferenceServiceException {
		if (currentDepth < 0)
			throw new ReferenceServiceException("Cannot register at depth "
					+ currentDepth + ": " + o);
		/*
		 * First check whether this is an Identified, and if so whether it
		 * already has an ID. If this is the case then return it, we assume that
		 * anything which has an identifier already allocated must have been
		 * registered (this is implicit in the contract for the various
		 * sub-services
		 */
		if (o instanceof Identified) {
			Identified i = (Identified) o;
			if (i.getId() != null)
				return i.getId();
		}
		/*
		 * Then check whether the item *is* a T2Reference, in which case we can
		 * just return it (useful for when registering lists of existing
		 * references)
		 */
		if (o instanceof T2Reference)
			return (T2Reference) o;

		if (o.getClass().isArray()) {
			Class<?> elementType = o.getClass().getComponentType();
			if (elementType.getCanonicalName().equals("char")) {
				char[] cArray = (char[]) o;
				List<Character> cList = new ArrayList<>();
				for (char c : cArray)
					cList.add(new Character(c));
				o = cList;
			} else if (elementType.getCanonicalName().equals("short")) {
				short[] cArray = (short[]) o;
				List<Short> cList = new ArrayList<>();
				for (short c : cArray)
					cList.add(new Short(c));
				o = cList;
			} else if (elementType.getCanonicalName().equals("int")) {
				int[] cArray = (int[]) o;
				List<Integer> cList = new ArrayList<>();
				for (int c : cArray)
					cList.add(new Integer(c));
				o = cList;
			} else if (elementType.getCanonicalName().equals("long")) {
				long[] cArray = (long[]) o;
				List<Long> cList = new ArrayList<>();
				for (long c : cArray)
					cList.add(new Long(c));
				o = cList;
			} else if (elementType.getCanonicalName().equals("float")) {
				float[] cArray = (float[]) o;
				List<Float> cList = new ArrayList<>();
				for (float c : cArray)
					cList.add(new Float(c));
				o = cList;
			} else if (elementType.getCanonicalName().equals("double")) {
				double[] cArray = (double[]) o;
				List<Double> cList = new ArrayList<>();
				for (double c : cArray)
					cList.add(new Double(c));
				o = cList;
			} else if (elementType.getCanonicalName().equals("boolean")) {
				boolean[] cArray = (boolean[]) o;
				List<Boolean> cList = new ArrayList<>();
				for (boolean c : cArray)
					cList.add(new Boolean(c));
				o = cList;
			} else if (!elementType.getCanonicalName().equals("byte")) {
				// Covert arrays of objects
				Object[] cArray = (Object[]) o;
				List<Object> cList = new ArrayList<>();
				for (Object c : cArray)
					cList.add(c);
				o = cList;
			}
		}

		// If a Collection but not a List
		if ((o instanceof Collection) && !(o instanceof List)) {
			List<Object> cList = new ArrayList<>();
			cList.addAll((Collection<Object>) o);
			o = cList;
		}
		// Next check lists.
		if (o instanceof List) {
			if (currentDepth < 1)
				throw new ReferenceServiceException(
						"Cannot register list at depth " + currentDepth);
			List<?> l = (List<?>) o;
			/*
			 * If the list is empty then register a new empty list of the
			 * appropriate depth and return it
			 */
			if (l.isEmpty())
				try {
					return listService.registerEmptyList(currentDepth, context)
							.getId();
				} catch (ListServiceException lse) {
					throw new ReferenceServiceException(lse);
				}
			/*
			 * Otherwise construct a new list of T2Reference and register it,
			 * calling the getNameForObject method on all children of the list
			 * to construct the list of references
			 */
			else {
				List<T2Reference> references = new ArrayList<>();
				for (Object item : l)
					/*
					 * Recursively call this method with a depth one lower than
					 * the current depth
					 */
					references.add(getNameForObject(item, currentDepth - 1,
							useConverterSPI, context));
				try {
					return listService.registerList(references, context)
							.getId();
				} catch (ListServiceException lse) {
					throw new ReferenceServiceException(lse);
				}
			}
		} else {
			/*
			 * Neither a list nor an already identified object, first thing is
			 * to engage the converters if enabled. Only engage if we don't
			 * already have a Throwable or an ExternalReferenceSPI instance
			 */
			if (useConverterSPI && (o instanceof Throwable == false)
					&& (o instanceof ExternalReferenceSPI == false)) {
				if (currentDepth != 0)
					throw new ReferenceServiceException(
							"Cannot register object " + o + " at depth "
									+ currentDepth);

				for (ValueToReferenceConverterSPI converter : converters)
					if (converter.canConvert(o, context))
						try {
							o = converter.convert(o, context);
							break;
						} catch (ValueToReferenceConversionException vtrce) {
							/*
							 * Fail, but that doesn't matter at the moment as
							 * there may be more converters to try.
							 * 
							 * TODO - log this!
							 */
						}
			}
			/*
			 * If the object is neither a Throwable nor an ExternalReferenceSPI
			 * instance at this point we should fail the registration process,
			 * this means either that the conversion process wasn't enabled or
			 * that it failed to map the object type correctly.
			 */
			if (!(o instanceof Throwable)
					&& !(o instanceof ExternalReferenceSPI))
				throw new ReferenceServiceException(
						"Failed to register object "
								+ o
								+ ", found a type '"
								+ o.getClass().getCanonicalName()
								+ "' which cannot currently be registered with the reference manager");

			// Have either a Throwable or an ExternalReferenceSPI
			if (o instanceof Throwable)
				// Wrap in an ErrorDocument and return the ID
				try {
					ErrorDocument doc = errorDocumentService.registerError(
							(Throwable) o, currentDepth, context);
					return doc.getId();
				} catch (ErrorDocumentServiceException edse) {
					throw new ReferenceServiceException(edse);
				}
			if (o instanceof ExternalReferenceSPI) {
				if (currentDepth != 0)
					throw new ReferenceServiceException(
							"Cannot register external references at depth "
									+ currentDepth);
				try {
					Set<ExternalReferenceSPI> references = new HashSet<ExternalReferenceSPI>();
					references.add((ExternalReferenceSPI) o);
					ReferenceSet rs = referenceSetService.registerReferenceSet(
							references, context);
					return rs.getId();
				} catch (ReferenceSetServiceException rsse) {
					throw new ReferenceServiceException(rsse);
				}
			}
		}
		throw new ReferenceServiceException(
				"Should never see this, reference registration"
						+ " logic has fallen off the end of the"
						+ " world, check the code!");
	}