Skip to main content
summaryrefslogblamecommitdiffstats
blob: 46191613c8e97ab07cd76e17cddabc369ffa1346 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                                
                                                                          
                                                                   



                                                                        

                                                                          

                                                                                 

                                                       
                            


















                                                              
                              
                                                                     








































































































































































































































































































                                                                                                                                                     

 
/*******************************************************************************
 * Copyright (c) 2005, 2007 committers of openArchitectureWare and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     committers of openArchitectureWare - initial API and implementation
 *******************************************************************************/

package org.eclipse.internal.xtend.type.baseimpl.types;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.internal.xtend.type.baseimpl.OperationImpl;
import org.eclipse.internal.xtend.type.baseimpl.PropertyImpl;
import org.eclipse.internal.xtend.util.StringHelper;
import org.eclipse.xtend.expression.TypeSystem;
import org.eclipse.xtend.typesystem.Feature;
import org.eclipse.xtend.typesystem.Type;

/**
 * @author Sven Efftinge (http://www.efftinge.de)
 * @author Arno Haase
 */
@SuppressWarnings("unchecked")
public class StringTypeImpl extends BuiltinBaseType implements Type {
	final Log log = LogFactory.getLog(getClass());

	public StringTypeImpl(final TypeSystem ts, final String name) {
		super(ts, name);
	}

	public boolean isInstance(final Object o) {
		return o instanceof String || o instanceof StringBuffer || o instanceof Character;
	}

	public Object newInstance() {
		return "";
	}

	@Override
	public Feature[] getContributedFeatures() {
		return new Feature[] {
				new PropertyImpl(this, "length", getTypeSystem().getIntegerType()) {

					@Override
					public String getDocumentation() {
						return "the length of this string";
					}

					public Object get(final Object target) {
						return new Long(target.toString().length());
					}
				},

				new OperationImpl(this, "+", getTypeSystem().getStringType(), new Type[] { getTypeSystem()
						.getObjectType() }) {

					@Override
					public String getDocumentation() {
						return "concatenates two strings";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return target.toString() + params[0];
					}
				},

				new OperationImpl(this, "startsWith", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem()
						.getStringType() }) {

					@Override
					public String getDocumentation() {
						return "Tests if this string starts with the specified prefix.";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						final String token = (String) params[0];
						return new Boolean(target.toString().startsWith(token));
					}
				},
				new OperationImpl(this, "contains", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem()
						.getStringType() }) {

					@Override
					public String getDocumentation() {
						return "Tests if this string contains substring.";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						final String token = (String) params[0];
						return new Boolean(target.toString().indexOf(token) >= 0);
					}
				},
				new OperationImpl(this, "endsWith", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem()
						.getStringType() }) {

					@Override
					public String getDocumentation() {
						return "Tests if this string ends with the specified prefix.";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						final String token = (String) params[0];
						return new Boolean(target.toString().endsWith(token));
					}
				},
				new OperationImpl(this, "subString", getTypeSystem().getStringType(), new Type[] {
						getTypeSystem().getIntegerType(), getTypeSystem().getIntegerType() }) {

					@Override
					public String getDocumentation() {
						return "Returns a new string that is a substring of this string.";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						final Number from = (Number) params[0];
						final Number to = (Number) params[1];
						return target.toString().substring(from.intValue(), to.intValue());
					}
				},

				new OperationImpl(this, "toUpperCase", getTypeSystem().getStringType(), new Type[] {}) {

					@Override
					public String getDocumentation() {
						return "Converts all of the characters in this String to upper"
								+ " case using the rules of the default locale (from Java)";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return target.toString().toUpperCase();
					}
				},

				new OperationImpl(this, "toLowerCase", getTypeSystem().getStringType(), new Type[] {}) {
					@Override
					public String getDocumentation() {
						return "Converts all of the characters in this String to lower"
								+ " case using the rules of the default locale (from Java)";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return target.toString().toLowerCase();
					}
				},

				new OperationImpl(this, "toFirstUpper", getTypeSystem().getStringType(), new Type[] {}) {
					@Override
					public String getDocumentation() {
						return "Converts the first character in this String to upper"
								+ " case using the rules of the default locale (from Java)";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return StringHelper.firstUpper(target.toString());
					}
				},

				new OperationImpl(this, "toFirstLower", getTypeSystem().getStringType(), new Type[] {}) {
					@Override
					public String getDocumentation() {
						return "Converts the first character in this String to lower"
								+ " case using the rules of the default locale (from Java)";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return StringHelper.firstLower(target.toString());
					}
				},

				new OperationImpl(this, "toCharList", getTypeSystem().getListType(getTypeSystem().getStringType()),
						new Type[] {}) {

					@Override
					public String getDocumentation() {
						return "splits this String into a List[String] containing Strings of length 1";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						final String txt = target.toString();
						final List<String> result = new ArrayList<String>();
						final char[] chars = txt.toCharArray();
						for (int i = 0; i < chars.length; i++) {
							result.add(String.valueOf(chars[i]));
						}
						return result;
					}
				},

				new OperationImpl(this, "replaceAll", getTypeSystem().getStringType(), new Type[] {
						getTypeSystem().getStringType(), getTypeSystem().getStringType() }) {

					@Override
					public String getDocumentation() {
						return "Replaces each substring of this string that matches the given "
								+ "regular expression with the given replacement.";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return target.toString().replaceAll(params[0].toString(), params[1].toString());
					}
				},

				new OperationImpl(this, "replaceFirst", getTypeSystem().getStringType(), new Type[] {
						getTypeSystem().getStringType(), getTypeSystem().getStringType() }) {

					@Override
					public String getDocumentation() {
						return "Replaces the first substring of this string that matches the given"
								+ " regular expression with the given replacement.";
					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return target.toString().replaceFirst(params[0].toString(), params[1].toString());
					}
				},

				new OperationImpl(this, "split", getTypeSystem().getListType(getTypeSystem().getStringType()),
						new Type[] { getTypeSystem().getStringType() }) {

					@Override
					public String getDocumentation() {
						return "Splits this string around matches of the given regular expression (from Java 1.4)";

					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return new ArrayList<String>(Arrays.asList(target.toString().split(params[0].toString())));
					}
				},

				new OperationImpl(this, "matches", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem()
						.getStringType() }) {

					@Override
					public String getDocumentation() {
						return "Tells whether or not this string matches the given regular expression. (from Java 1.4)";

					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return Boolean.valueOf(((String) target).matches((String) params[0]));
					}
				},

				new OperationImpl(this, "trim", getTypeSystem().getStringType(), new Type[] {}) {

					@Override
					public String getDocumentation() {
						return "Returns a copy of the string, with leading and trailing whitespace omitted. (from Java 1.4)";

					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						return ((String) target).trim();
					}
				},

				new OperationImpl(this, "asInteger", getTypeSystem().getIntegerType(), new Type[] {}) {

					@Override
					public String getDocumentation() {
						return "Returns an Integer object holding the value of the specified String (from Java 1.5)";

					}

					@Override
					public Object evaluateInternal(final Object target, final Object[] params) {
						try {
							return new BigInteger((String) target);
						}
						catch (NumberFormatException nfe) {
							log.error("'asInteger' on '" + target + "' returned null!");
							return null;
						}
					}
				}

		};
	}

	@Override
	public Set<Type> getSuperTypes() {
		return Collections.singleton(getTypeSystem().getObjectType());
	}

	private String toString(final Object o) {
		if (o == null)
			return null;
		if (isInstance(o))
			return o.toString();
		throw new IllegalArgumentException(o.getClass().getName() + " not supported");
	}

	@Override
	public Object convert(final Object src, final Class targetType) {
		final String s = toString(src);
		if (targetType.isAssignableFrom(String.class))
			return s;
		else if (targetType.isAssignableFrom(Character.class) || targetType.isAssignableFrom(Character.TYPE)) {
			if (s.length() == 1)
				return new Character(s.charAt(0));
		}
		else if (targetType.isAssignableFrom(StringBuffer.class))
			return new StringBuffer(s);
		return super.convert(src, targetType);
	}

}

Back to the top