org.ldp4j.application.kernel.impl.InMemoryContainer.java Source code

Java tutorial

Introduction

Here is the source code for org.ldp4j.application.kernel.impl.InMemoryContainer.java

Source

/**
 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
 *   This file is part of the LDP4j Project:
 *     http://www.ldp4j.org/
 *
 *   Center for Open Middleware
 *     http://www.centeropenmiddleware.com/
 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
 *   Copyright (C) 2014-2016 Center for Open Middleware.
 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
 *   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.
 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
 *   Artifact    : org.ldp4j.framework:ldp4j-application-kernel-mem:0.2.1
 *   Bundle      : ldp4j-application-kernel-mem-0.2.1.jar
 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
 */
package org.ldp4j.application.kernel.impl;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

import org.ldp4j.application.kernel.resource.Container;
import org.ldp4j.application.kernel.resource.Member;
import org.ldp4j.application.kernel.resource.Resource;
import org.ldp4j.application.kernel.resource.ResourceId;
import org.ldp4j.application.kernel.resource.ResourceVisitor;
import org.ldp4j.application.kernel.resource.Slug;
import org.ldp4j.application.kernel.template.ContainerTemplate;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;

final class InMemoryContainer extends InMemoryResource implements Container {

    private static final class InMemoryMember implements Member {

        private final ResourceId memberId;
        private final ResourceId containerId;
        private final long number;

        private InMemoryMember(ResourceId containerId, ResourceId memberId, long number) {
            this.memberId = memberId;
            this.containerId = containerId;
            this.number = number;
        }

        @Override
        public long number() {
            return number;
        }

        @Override
        public ResourceId containerId() {
            return containerId;
        }

        @Override
        public ResourceId memberId() {
            return memberId;
        }

        @Override
        public String toString() {
            return MoreObjects.toStringHelper(getClass()).add("number", this.number)
                    .add("containerId", this.containerId).add("memberId", this.memberId).toString();
        }

    }

    private final ConcurrentMap<ResourceId, Member> members;
    private final AtomicLong memberCounter;
    private final ConcurrentMap<String, InMemorySlug> slugs;

    InMemoryContainer(ResourceId id, ResourceId parentId) {
        super(id, parentId);
        this.members = Maps.newConcurrentMap();
        this.memberCounter = new AtomicLong();
        this.slugs = Maps.newConcurrentMap();
    }

    InMemoryContainer(ResourceId id) {
        this(id, null);
    }

    private Member createMember(InMemoryResource newResource) {
        InMemoryMember member = new InMemoryMember(id(), newResource.id(), this.memberCounter.incrementAndGet());
        Member result = this.members.putIfAbsent(member.memberId(), member);
        if (result == null) {
            result = member;
        }
        return result;
    }

    private InMemoryResource createMemberResource(ResourceId resourceId) {
        checkNotNull(resourceId, "Member resource identifier cannot be null");
        checkState(!this.members.containsKey(resourceId),
                "A resource with id '%s' is already a member of the container", resourceId);
        return createChild(resourceId, template().memberTemplate());
    }

    private ContainerTemplate template() {
        return (ContainerTemplate) super.getTemplate(id());
    }

    @Override
    public void accept(ResourceVisitor visitor) {
        visitor.visitContainer(this);
    }

    @Override
    public Resource addMember(ResourceId resourceId) {
        InMemoryResource newResource = createMemberResource(resourceId);
        createMember(newResource);
        return newResource;
    }

    @Override
    public boolean hasMember(ResourceId resource) {
        return this.members.containsKey(resource);
    }

    @Override
    public Set<Member> members() {
        return ImmutableSet.copyOf(members.values());
    }

    @Override
    public Member findMember(ResourceId resourceId) {
        return this.members.get(resourceId);
    }

    @Override
    public boolean removeMember(Member member) {
        checkNotNull(member, "Member cannot be null");
        return members.remove(member.memberId(), member);
    }

    @Override
    public Set<Slug> slugs() {
        return ImmutableSet.<Slug>copyOf(this.slugs.values());
    }

    @Override
    public Slug findSlug(String preferredPath) {
        return this.slugs.get(preferredPath);
    }

    @Override
    public Slug addSlug(String preferredPath) {
        checkNotNull(preferredPath, "Preferred path cannot be null");

        InMemorySlug tmp = InMemorySlug.create(preferredPath, this);

        InMemorySlug slug = this.slugs.putIfAbsent(tmp.preferredPath(), tmp);
        if (slug == null) {
            return tmp;
        }

        synchronized (slug) {
            if (slug.version() < tmp.version()) {
                slug.setVersion(tmp.version());
                return slug;
            } else if (slug.version() == tmp.version()) {
                return slug;
            }
        }

        return addSlug(preferredPath + "_1");
    }

    @Override
    public String toString() {
        return stringHelper().add("memberCounter", this.memberCounter).add("members", this.members)
                .add("slugs", this.slugs).toString();
    }

}