/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */
package org.apache.jdo.tck.api.persistencemanagerfactory.config;

import java.util.HashMap;
import java.util.Map;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B>JDOConfigListener <br>
 * <B>Keywords:</B> persistencemanagerfactory, jdoconfig.xml <br>
 * <B>Assertion IDs:</B> A11.1-40 <br>
 * <B>Assertion Description: </B> Properties whose key begins with the prefix
 * "javax.jdo.listener.InstanceLifecycleListener." have special treatment. The part of the key
 * following the prefix is used as the class name of a class that implements
 * javax.jdo.listener.InstanceLifecycleListener. The implementation first attempts to get an
 * instance via the static method getInstance() that returns an instance that implements the
 * javax.jdo.listener.InstanceLifecycleListener. If this is unsuccessful, an instance of this class
 * is constructed via a no-args constructor. The value of the key is a comma-separated list of
 * classes to which the instantiated listener is registered to listen.
 */
public class JDOConfigListener extends JDO_Test {

  /** Creates a new instance of JDOConfigListener */
  public JDOConfigListener() {}
  /** */
  private static final String ASSERTION_FAILED = "Assertions 11.1-40 failed: ";

  private static final String ANONYMOUS_PMF_NAME = "";
  // Do not use superclass pmf, pm
  private PersistenceManagerFactory pmf = null;
  private PersistenceManager pm = null;
  private final Map<String, String> overrides = new HashMap<>();

  /**
   * The <code>main</code> is called when the class is directly executed from the command line.
   *
   * @param args The arguments passed to the program.
   */
  public static void main(String[] args) {
    BatchTestRunner.run(JDOConfigListener.class);
  }

  /**
   * @see org.apache.jdo.tck.JDO_Test#localSetUp()
   */
  @Override
  protected void localSetUp() {
    /* Instance can be persisted ONLY if javax.jdo.mapping.Schema
     *   is overriden with
     *   JDOHelper.getPersistenceManagerFactory(Map overrides, ...).
     *   The value depends on identity type so can only be known at runtime.
     */
    if (isTestToBePerformed()) {
      overrides.put("javax.jdo.mapping.Schema", SCHEMANAME);
    }
  }

  /**
   * Test instantiation of InstanceLifecycleListener where listener class and target classes are
   * specified in jdoconfig.xml where listener class provides only a public no-args constructor.
   */
  public void testPCPointListener() {
    String pmfname = "testInstanceLifecycleListenerStore";
    pmf = JDOHelper.getPersistenceManagerFactory(overrides, pmfname);
    makePersistent();
    assertTrue("Expected preStore() to have been invoked.", StoreListener.isPreStore());
    assertTrue("Expected postStore() to have been invoked.", StoreListener.isPostStore());
  }

  /**
   * Test instantiation of InstanceLifecycleListener where listener class and target classes are
   * specified in jdoconfig.xml where listener class provides a static method getInstance().
   */
  public void testPCPointListenerGetInstance() {
    String pmfname = "testInstanceLifecycleListenerStoreGetInstance";
    pmf = JDOHelper.getPersistenceManagerFactory(overrides, pmfname);
    makePersistent();
    assertTrue("Expected preStore() to have been invoked.", StoreListenerGetInstance.isPreStore());
    assertTrue(
        "Expected postStore() to have been invoked.", StoreListenerGetInstance.isPostStore());
  }

  /** Test instantiation of Instance LifeCycleListener specified via property overrides. */
  public void testPCPointListenerOverrides() {
    overrides.put(
        "javax.jdo.listener.InstanceLifecycleListener.org.apache.jdo.tck.api.persistencemanagerfactory.config.StoreListener",
        "org.apache.jdo.tck.pc.mylib.PCPoint");
    String pmfname = "testInstanceLifecycleListenerStoreOverrides";
    pmf = JDOHelper.getPersistenceManagerFactory(overrides, pmfname);
    makePersistent();
    assertTrue("Expected preStore() to have been invoked.", StoreListener.isPreStore());
    assertTrue("Expected postStore() to have been invoked.", StoreListener.isPostStore());
  }

  /** Test instantiation of InstanceLifecycleListener where class value is null */
  public void testPCPointListenerNullClasses() {
    String pmfname = "testInstanceLifecycleListenerClassesNull";
    pmf = JDOHelper.getPersistenceManagerFactory(overrides, pmfname);
    makePersistent();
    assertTrue("Expected preStore() to have been invoked.", StoreListener.isPreStore());
    assertTrue("Expected postStore() to have been invoked.", StoreListener.isPostStore());
  }

  protected void makePersistent() {
    addTearDownClass(PCPoint.class);
    pm = pmf.getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    tx.begin();
    PCPoint comp = new PCPoint(1, 2);
    pm.makePersistent(comp);
    tx.commit();
  }

  @Override
  protected void localTearDown() {
    super.localTearDown();
    StoreListener.resetValues();
    StoreListenerGetInstance.resetValues();
    closePMF();
  }
}
