Package org.cyclop.service.queryprotocoling.intern

Source Code of org.cyclop.service.queryprotocoling.intern.AbstractQueryProtocolingService

/*
* 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.cyclop.service.queryprotocoling.intern;

import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

import javax.inject.Inject;
import javax.inject.Named;
import javax.validation.constraints.NotNull;

import net.jcip.annotations.NotThreadSafe;

import org.cyclop.model.UserIdentifier;
import org.cyclop.service.common.FileStorage;
import org.cyclop.service.queryprotocoling.QueryProtocolingService;
import org.cyclop.service.um.UserManager;
import org.cyclop.validation.EnableValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;

/** @author Maciej Miklas */
@NotThreadSafe
@Named
@EnableValidation
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
abstract class AbstractQueryProtocolingService<H> implements QueryProtocolingService<H> {

  private final static Logger LOG = LoggerFactory.getLogger(AbstractQueryProtocolingService.class);

  private final AtomicReference<H> history = new AtomicReference<>();

  @Inject
  private UserManager um;

  @Inject
  private FileStorage storage;

  @Inject
  private AsyncFileStore<H> asyncFileStore;

  private UserIdentifier identifier;

  protected abstract Class<H> getClazz();

  protected abstract H createEmpty();

  protected UserIdentifier getUser() {
    final UserIdentifier fromCookie = um.readIdentifier();
    if (identifier == null) {
      LOG.debug("Using identifier from cookie: {}", fromCookie);
      identifier = fromCookie;
    } else {

      // make sure that there is only one user identifier pro http session
      // if it's not the case overwrite new one with existing one
      if (!fromCookie.equals(identifier)) {
        LOG.debug("Replacing {} with {}", fromCookie, identifier);
        um.storeIdentifier(identifier);
      }
    }
    return identifier;
  }

  @Override
  public void store(@NotNull H newHistory) {
    LOG.debug("String history");
    history.set(newHistory);
    final UserIdentifier user = getUser();

    // this synchronization ensures that history will be not added to write
    // queue while it's being read from
    // disk in #readHistory()
    synchronized (asyncFileStore) {
      asyncFileStore.store(user, newHistory);
    }
  }

  @Override
  public @NotNull H read() {
    LOG.debug("Accessing history");
    if (history.get() == null) {
      synchronized (asyncFileStore) {
        LOG.debug("Reading history");
        if (history.get() == null) {
          final UserIdentifier user = getUser();

          // history can be in write queue when user closes http
          // session and opens new few seconds later.
          // in this case async queue might be not flushed to disk yet
          final Optional<H> readOpt = asyncFileStore.getFromWriteQueue(user);
          H read = null;
          if (!readOpt.isPresent()) {
            read = storage.read(user, getClazz()).orElse(createEmpty());
          }
          history.set(read);
        }
      }
    }
    return history.get();
  }

  @Override
  public boolean supported() {
    return storage.supported();
  }
}
TOP

Related Classes of org.cyclop.service.queryprotocoling.intern.AbstractQueryProtocolingService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.