All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.solovyev.common.math.AbstractMathRegistry Maven / Gradle / Ivy

/*
 * Copyright 2013 serso aka se.solovyev
 *
 * Licensed 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.
 *
 * ---------------------------------------------------------------------
 * Contact details
 *
 * Email: [email protected]
 * Site:  http://se.solovyev.org
 */

package org.solovyev.common.math;

import org.solovyev.common.JBuilder;
import org.solovyev.common.JPredicate;
import org.solovyev.common.collections.SortedList;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

import static org.solovyev.common.collections.Collections.find;
import static org.solovyev.common.collections.Collections.removeFirst;

/**
 * User: serso
 * Date: 9/29/11
 * Time: 4:57 PM
 */
public abstract class AbstractMathRegistry implements MathRegistry {

	private static final MathEntityComparator MATH_ENTITY_COMPARATOR = new MathEntityComparator();

	static class MathEntityComparator implements Comparator {

		MathEntityComparator() {
		}

		@Override
		public int compare(T l, T r) {
			int result = r.getName().length() - l.getName().length();
			if (result == 0) {
				result = l.getName().compareTo(r.getName());
			}
			return result;
		}
	}

	@GuardedBy("this")
	@Nonnull
	private static volatile Integer counter = 0;

	@GuardedBy("this")
	@Nonnull
	protected final SortedList entities = SortedList.newInstance(new ArrayList(30), MATH_ENTITY_COMPARATOR);

	@GuardedBy("this")
	@Nonnull
	protected final SortedList systemEntities = SortedList.newInstance(new ArrayList(30), MATH_ENTITY_COMPARATOR);

	protected AbstractMathRegistry() {
	}

	@Nonnull
	@Override
	public List getEntities() {
		synchronized (this) {
			return java.util.Collections.unmodifiableList(new ArrayList(entities));
		}
	}

	@Nonnull
	@Override
	public List getSystemEntities() {
		synchronized (this) {
			return java.util.Collections.unmodifiableList(new ArrayList(systemEntities));
		}
	}

	protected void add(@Nonnull T entity) {
		synchronized (this) {
			if (entity.isSystem()) {
				if (contains(entity.getName(), this.systemEntities)) {
					throw new IllegalArgumentException("Trying to add two system entities with same name: " + entity.getName());
				}

				this.systemEntities.add(entity);
			}

			if (!contains(entity.getName(), this.entities)) {
				addEntity(entity, this.entities);
			}
		}
	}

	private void addEntity(@Nonnull T entity, @Nonnull List list) {
		assert Thread.holdsLock(this);

		entity.setId(count());
		list.add(entity);
	}

	@Override
	public T add(@Nonnull JBuilder builder) {
		synchronized (this) {
			final T entity = builder.create();

			T varFromRegister;

			if (entity.isIdDefined()) {
				varFromRegister = getById(entity.getId());
			} else {
				varFromRegister = get(entity.getName());
			}

			if (varFromRegister == null) {
				varFromRegister = entity;

				addEntity(entity, this.entities);
				if (entity.isSystem()) {
					this.systemEntities.add(entity);
				}

			} else {
				varFromRegister.copy(entity);
				this.entities.sort();
				this.systemEntities.sort();
			}

			return varFromRegister;
		}
	}

	@Override
	public void remove(@Nonnull T entity) {
		synchronized (this) {
			if (!entity.isSystem()) {
				removeFirst(this.entities, new MathEntity.Finder(entity.getName()));
			}
		}
	}

	@Override
	@Nonnull
	public List getNames() {
		final List result = new ArrayList(entities.size());

		synchronized (this) {
			for (T entity : entities) {
				result.add(entity.getName());
			}
		}

		return result;
	}

	@Override
	@Nullable
	public T get(@Nonnull final String name) {
		synchronized (this) {
			return find(entities, new MathEntity.Finder(name));
		}
	}

	@Override
	public T getById(@Nonnull final Integer id) {
		synchronized (this) {
			return find(entities, new JPredicate() {
				@Override
				public boolean apply(@Nullable T t) {
					return t != null && t.getId().equals(id);
				}
			});
		}
	}

	@Override
	public boolean contains(@Nonnull final String name) {
		synchronized (this) {
			return contains(name, this.entities);
		}
	}

	private boolean contains(final String name, @Nonnull Collection entities) {
		synchronized (this) {
			return find(entities, new MathEntity.Finder(name)) != null;
		}
	}

	@Nonnull
	private static synchronized Integer count() {
		final Integer result = counter;
		counter++;
		return result;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy