/**
   * DOC amaumont Comment method "beforeLoopFind".
   *
   * @throws IOException
   */
  private void beforeLoopFind() throws IOException {
    // File file = new File(workDirectory + "TEMP_" + count);

    // DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new
    // FileOutputStream(file)));
    int numFiles = files.size();
    diss = new ArrayList<DataInputStream>();
    datas = new ArrayList<DataContainer>();
    fileLengths = new ArrayList<Long>();

    boolean someFileStillHasRows = false;

    for (int i = 0; i < numFiles; i++) {
      diss.add(new DataInputStream(new BufferedInputStream(new FileInputStream(files.get(i)))));
      fileLengths.add(files.get(i).length());
      DataContainer dc = new DataContainer();
      DataInputStream dis = diss.get(i);
      byte[] bytes = new byte[dis.readInt()];
      dis.read(bytes);
      dc.object = iLightSerializable.createInstance(bytes);
      if (!someFileStillHasRows) {
        someFileStillHasRows = true;
      }
      datas.add(dc);
    }
  }
 private void assertContainerEntry(
     Class<? extends InternalCacheEntry> type, String expectedValue) {
   assert dc.containsKey("k");
   InternalCacheEntry entry = dc.get("k");
   assertEquals(type, entry.getClass());
   assertEquals(expectedValue, entry.getValue());
 }
  protected <O> O instantiate(int id, DataContainer container, ClassTypeModel<O> typeModel)
      throws IOException {
    Map<FieldModel<? super O, ?>, Object> state = new HashMap<FieldModel<? super O, ?>, Object>();
    ClassTypeModel<? super O> currentTypeModel = typeModel;
    List<FieldUpdate<O>> sets = new ArrayList<FieldUpdate<O>>();
    while (currentTypeModel != null) {
      if (currentTypeModel instanceof ClassTypeModel) {
        for (FieldModel<? super O, ?> fieldModel : currentTypeModel.getFields()) {
          if (!fieldModel.isTransient()) {
            switch (container.readInt()) {
              case DataKind.NULL_VALUE:
                state.put(fieldModel, null);
                break;
              case DataKind.OBJECT_REF:
                int refId = container.readInt();
                Object refO = idToObject.get(refId);
                if (refO != null) {
                  state.put(fieldModel, refO);
                } else {
                  sets.add(new FieldUpdate<O>(refId, fieldModel));
                }
                break;
              case DataKind.OBJECT:
                Object o = container.readObject();
                state.put(fieldModel, o);
                break;
            }
          }
        }
      }
      currentTypeModel = currentTypeModel.getSuperType();
    }

    //
    O instance = instantiate(typeModel, state);

    // Create future field updates
    for (FieldUpdate<O> set : sets) {
      List<FutureFieldUpdate<?>> resolutions = idToResolutions.get(set.ref);
      if (resolutions == null) {
        resolutions = new ArrayList<FutureFieldUpdate<?>>();
        idToResolutions.put(set.ref, resolutions);
      }
      resolutions.add(new FutureFieldUpdate<O>(instance, set.fieldModel));
    }

    //
    idToObject.put(id, instance);

    // Resolve future field updates
    List<FutureFieldUpdate<?>> resolutions = idToResolutions.remove(id);
    if (resolutions != null) {
      for (FutureFieldUpdate<?> resolution : resolutions) {
        resolution.fieldModel.castAndSet(resolution.target, instance);
      }
    }

    //
    return instance;
  }
Example #4
0
  private Object interpretFunctionListItem(Object left, Sprite sprite) {
    UserList userList = null;
    if (rightChild.getElementType() == ElementType.USER_LIST) {
      DataContainer dataContainer =
          ProjectManager.getInstance().getSceneToPlay().getDataContainer();
      userList = dataContainer.getUserList(rightChild.getValue(), sprite);
    }

    if (userList == null) {
      return "";
    }

    int index = 0;
    if (left instanceof String) {
      try {
        Double doubleValueOfLeftChild = Double.valueOf((String) left);
        index = doubleValueOfLeftChild.intValue();
      } catch (NumberFormatException numberFormatexception) {
        Log.d(getClass().getSimpleName(), "Couldn't parse String", numberFormatexception);
      }
    } else {
      index = ((Double) left).intValue();
    }

    index--;

    if (index < 0) {
      return "";
    } else if (index >= userList.getList().size()) {
      return "";
    }

    return userList.getList().get(index);
  }
  public void testUpdatingLastUsed() throws Exception {
    long idle = 600000;
    dc.put("k", "v", -1, -1);
    InternalCacheEntry ice = dc.get("k");
    assert ice.getClass().equals(immortaltype());
    assert ice.getExpiryTime() == -1;
    assert ice.getMaxIdle() == -1;
    assert ice.getLifespan() == -1;
    dc.put("k", "v", -1, idle);
    long oldTime = System.currentTimeMillis();
    Thread.sleep(100); // for time calc granularity
    ice = dc.get("k");
    assert ice.getClass().equals(transienttype());
    assert ice.getExpiryTime() > -1;
    assert ice.getLastUsed() > oldTime;
    Thread.sleep(100); // for time calc granularity
    assert ice.getLastUsed() < System.currentTimeMillis();
    assert ice.getMaxIdle() == idle;
    assert ice.getLifespan() == -1;

    oldTime = System.currentTimeMillis();
    Thread.sleep(100); // for time calc granularity
    assert dc.get("k") != null;

    // check that the last used stamp has been updated on a get
    assert ice.getLastUsed() > oldTime;
    Thread.sleep(100); // for time calc granularity
    assert ice.getLastUsed() < System.currentTimeMillis();
  }
  /**
   * DOC amaumont Comment method "findNextData".
   *
   * @throws IOException
   */
  private void findNextData() throws IOException {
    DataContainer min = null;
    int minIndex = 0;
    DataContainer dataContainer = datas.get(0);

    if (dataContainer.object != null) {
      min = dataContainer;
      minIndex = 0;
    } else {
      min = null;
      minIndex = -1;
    }

    // check which one is min
    for (int i = 1; i < datas.size(); i++) {
      dataContainer = datas.get(i);

      if (min != null) {
        if (dataContainer.object != null
            && ((Comparable) (dataContainer.object)).compareTo(min.object) < 0) {
          minIndex = i;
          min = dataContainer;
        }
      } else {
        if (dataContainer.object != null) {
          min = dataContainer;
          minIndex = i;
        }
      }
    }

    if (minIndex < 0) {
      someFileStillHasRows = false;
    } else {
      // write to the sorted file
      // write(min.data, dos);

      currentObject = (V) min.object;

      min.reset();

      // get another data from the file
      DataInputStream dis = diss.get(minIndex);
      if (dis.available() > 0) {
        byte[] bytes = new byte[dis.readInt()];
        dis.read(bytes);
        min.object = iLightSerializable.createInstance(bytes);
        min.cursorPosition += 4 + bytes.length;
      }
      // check if one still has data
      someFileStillHasRows = false;
      for (int i = 0; i < datas.size(); i++) {
        if (datas.get(i).object != null) {
          someFileStillHasRows = true;
          break;
        }
      }
    }
  }
Example #7
0
 @Override
 public DataContainer toContainer() {
   DataContainer container = new MemoryDataContainer();
   container.set(DataQuery.of("myInt"), this.testInt);
   container.set(DataQuery.of("myDouble"), this.testDouble);
   container.set(DataQuery.of("myString"), this.testString);
   container.set(DataQuery.of("myStringList"), Arrays.asList(this.testList));
   return container;
 }
Example #8
0
  private int handleNumberOfItemsOfUserListParameter(Sprite sprite) {
    DataContainer dataContainer = ProjectManager.getInstance().getSceneToPlay().getDataContainer();
    UserList userList = dataContainer.getUserList(leftChild.value, sprite);

    if (userList == null) {
      return 0;
    }

    return userList.getList().size();
  }
Example #9
0
 public boolean isUserVariableWithTypeString(Sprite sprite) {
   if (type == ElementType.USER_VARIABLE) {
     DataContainer userVariableContainer =
         ProjectManager.getInstance().getSceneToPlay().getDataContainer();
     UserVariable userVariable = userVariableContainer.getUserVariable(value, sprite);
     Object userVariableValue = userVariable.getValue();
     return userVariableValue instanceof String;
   }
   return false;
 }
  public void testGetDuringKeySetLoop() {
    for (int i = 0; i < 10; i++) dc.put(i, "value", -1, -1);

    int i = 0;
    for (Object key : dc.keySet()) {
      dc.peek(key); // calling get in this situations will result on corruption the iteration.
      i++;
    }

    assert i == 10 : "Expected the loop to run 10 times, only ran " + i;
  }
Example #11
0
  private Object interpretUserVariable(Sprite sprite) {
    DataContainer userVariables = ProjectManager.getInstance().getSceneToPlay().getDataContainer();
    UserVariable userVariable = userVariables.getUserVariable(value, sprite);
    if (userVariable == null) {
      return NOT_EXISTING_USER_VARIABLE_INTERPRETATION_VALUE;
    }

    Object userVariableValue = userVariable.getValue();
    if (userVariableValue instanceof String) {
      return userVariableValue;
    } else {
      return userVariableValue;
    }
  }
Example #12
0
  private int handleLengthUserVariableParameter(Sprite sprite) {
    DataContainer userVariableContainer =
        ProjectManager.getInstance().getSceneToPlay().getDataContainer();
    UserVariable userVariable = userVariableContainer.getUserVariable(leftChild.value, sprite);

    Object userVariableValue = userVariable.getValue();
    if (userVariableValue instanceof String) {
      return String.valueOf(userVariableValue).length();
    } else {
      if (isInteger((Double) userVariableValue)) {
        return Integer.toString(((Double) userVariableValue).intValue()).length();
      } else {
        return Double.toString(((Double) userVariableValue)).length();
      }
    }
  }
  public void testValues() {
    dc.put("k1", "v1", 6000000, -1);
    dc.put("k2", "v2", -1, -1);
    dc.put("k3", "v3", -1, 6000000);
    dc.put("k4", "v4", 6000000, 6000000);

    Set expected = new HashSet();
    expected.add("v1");
    expected.add("v2");
    expected.add("v3");
    expected.add("v4");

    for (Object o : dc.values()) assert expected.remove(o);

    assert expected.isEmpty() : "Did not see keys " + expected + " in iterator!";
  }
Example #14
0
 /* (non-Javadoc)
  * @see java.lang.Object#hashCode()
  */
 @Override
 public int hashCode() {
   final int prime = 31;
   int result = 1;
   result = prime * result + ((dc == null) ? 0 : dc.hashCode());
   result = prime * result + ((fld == null) ? 0 : fld.hashCode());
   return result;
 }
  public void testContainerIteration() {
    dc.put("k1", "v", 6000000, -1);
    dc.put("k2", "v", -1, -1);
    dc.put("k3", "v", -1, 6000000);
    dc.put("k4", "v", 6000000, 6000000);

    Set expected = new HashSet();
    expected.add("k1");
    expected.add("k2");
    expected.add("k3");
    expected.add("k4");

    for (InternalCacheEntry ice : dc) {
      assert expected.remove(ice.getKey());
    }

    assert expected.isEmpty() : "Did not see keys " + expected + " in iterator!";
  }
Example #16
0
  private Object interpretFunctionContains(Object right, Sprite sprite) {
    if (leftChild.getElementType() == ElementType.USER_LIST) {
      DataContainer dataContainer =
          ProjectManager.getInstance().getSceneToPlay().getDataContainer();
      UserList userList = dataContainer.getUserList(leftChild.getValue(), sprite);

      if (userList == null) {
        return 0d;
      }

      for (Object userListElement : userList.getList()) {
        if (interpretOperatorEqual(userListElement, right) == 1d) {
          return 1d;
        }
      }
    }

    return 0d;
  }
Example #17
0
  private Object interpretFunctionLength(Object left, Sprite sprite) {
    if (leftChild == null) {
      return 0d;
    }
    if (leftChild.type == ElementType.NUMBER) {
      return (double) leftChild.value.length();
    }
    if (leftChild.type == ElementType.STRING) {
      return (double) leftChild.value.length();
    }
    if (leftChild.type == ElementType.USER_VARIABLE) {
      return (double) handleLengthUserVariableParameter(sprite);
    }
    if (leftChild.type == ElementType.USER_LIST) {
      DataContainer dataContainer =
          ProjectManager.getInstance().getSceneToPlay().getDataContainer();
      UserList userList = dataContainer.getUserList(leftChild.getValue(), sprite);
      if (userList == null) {
        return 0d;
      }
      if (userList.getList().size() == 0) {
        return 0d;
      }

      Object interpretedList = leftChild.interpretRecursive(sprite);
      if (interpretedList instanceof Double) {
        Double interpretedListDoubleValue = (Double) interpretedList;
        if (interpretedListDoubleValue.isNaN() || interpretedListDoubleValue.isInfinite()) {
          return 0d;
        }
        return (double) (String.valueOf(interpretedListDoubleValue.intValue())).length();
      }
      if (interpretedList instanceof String) {
        String interpretedListStringValue = (String) interpretedList;
        return (double) interpretedListStringValue.length();
      }
    }
    if (left instanceof Double && ((Double) left).isNaN()) {
      return 0d;
    }
    return (double) (String.valueOf(left)).length();
  }
Example #18
0
  public static void main(String[] args) {
    datacontainers.add(new HashMapDataContainer());
    datacontainers.add(new HardCodeBasicBeanDataContainer());
    datacontainers.add(new HardCodeWrapperBeanDataContainer());
    datacontainers.add(new ApacheDynaBeanDataContainer());
    datacontainers.add(new CglibBeanMapDataContainer());
    datacontainers.add(new DynamicBeanSetObjDataContainer());

    for (int i = 0; i < lens.length; i++) {
      System.out.println("data rows:" + lens[i]);
      for (DataContainer db : datacontainers) {
        Object obj = db.createRows(lens[i]);
        System.out.println(
            MemoryMeasurer.measureBytes(obj)
                + "  --DataContainer:"
                + db.getClass().getSimpleName().replace("DataContainer", ""));
        // System.out.println(ObjectGraphMeasurer.measure(obj));

      }
    }
  }
 private Object read(DataContainer container) throws IOException {
   int sw = container.readInt();
   switch (sw) {
     case DataKind.OBJECT_REF:
       {
         int id = container.readInt();
         Object o1 = idToObject.get(id);
         if (o1 == null) {
           throw new AssertionError();
         }
         return o1;
       }
     case DataKind.OBJECT:
       {
         int id = container.readInt();
         Class<?> clazz = (Class) container.readObject();
         ClassTypeModel<?> typeModel =
             (ClassTypeModel<?>) context.getTypeDomain().getTypeModel(clazz);
         return instantiate(id, container, typeModel);
       }
     case DataKind.CONVERTED_OBJECT:
       {
         Class<?> tclazz = (Class<?>) container.readObject();
         ConvertedTypeModel<?, ?> ctm =
             (ConvertedTypeModel<?, ?>) context.getTypeDomain().getTypeModel(tclazz);
         return convertObject(container, ctm);
       }
     case DataKind.SERIALIZED_OBJECT:
       return container.readObject();
     default:
       throw new StreamCorruptedException("Unrecognized data " + sw);
   }
 }
  public void testExpirableToImmortalAndBack() {
    String value = "v";
    dc.put("k", value, 6000000, -1);
    assertContainerEntry(mortaltype(), value);

    value = "v2";
    dc.put("k", value, -1, -1);
    assertContainerEntry(immortaltype(), value);

    value = "v3";
    dc.put("k", value, -1, 6000000);
    assertContainerEntry(transienttype(), value);

    value = "v4";
    dc.put("k", value, 6000000, 6000000);
    assertContainerEntry(transientmortaltype(), value);

    value = "v41";
    dc.put("k", value, 6000000, 6000000);
    assertContainerEntry(transientmortaltype(), value);

    value = "v5";
    dc.put("k", value, 6000000, -1);
    assertContainerEntry(mortaltype(), value);
  }
  /**
   * Analyzes the data file identified by the given resource name.
   *
   * @param aResourceName the name of the resource (= data file) to analyse, cannot be <code>null
   *     </code>.
   * @return the analysis results, never <code>null</code>.
   * @throws Exception in case of exceptions.
   */
  private I2CDataSet analyseDataFile(
      final String aResourceName, final int aSclIndex, final int aSdaIndex) throws Exception {
    URL resource = ResourceUtils.getResource(getClass(), aResourceName);
    DataContainer container = DataTestUtils.getCapturedData(resource);
    ToolContext toolContext = DataTestUtils.createToolContext(0, container.getValues().length);

    I2CAnalyserWorker worker = new I2CAnalyserWorker(container, toolContext);
    worker.setLineAIndex(aSclIndex);
    worker.setLineBIndex(aSdaIndex);
    worker.setDetectSDA_SCL(false);
    worker.setReportACK(false);
    worker.setReportNACK(false);
    worker.setReportStart(false);
    worker.setReportStop(false);

    // Simulate we're running in a separate thread by directly calling the main
    // working routine...
    I2CDataSet result = worker.doInBackground();
    assertNotNull(result);

    return result;
  }
Example #22
0
  private Object interpretUserList(Sprite sprite) {
    DataContainer dataContainer = ProjectManager.getInstance().getSceneToPlay().getDataContainer();
    UserList userList = dataContainer.getUserList(value, sprite);
    if (userList == null) {
      return NOT_EXISTING_USER_LIST_INTERPRETATION_VALUE;
    }

    List<Object> userListValues = userList.getList();

    if (userListValues.size() == 0) {
      return 0d;
    } else if (userListValues.size() == 1) {
      Object userListValue = userListValues.get(0);
      if (userListValue instanceof String) {
        return userListValue;
      } else {
        return userListValue;
      }
    } else {
      return interpretMultipleItemsUserList(userListValues);
    }
  }
  public void testEntrySet() {
    dc.put("k1", "v1", 6000000, -1);
    dc.put("k2", "v2", -1, -1);
    dc.put("k3", "v3", -1, 6000000);
    dc.put("k4", "v4", 6000000, 6000000);

    Set expected = new HashSet();
    expected.add(Immutables.immutableInternalCacheEntry(dc.get("k1")));
    expected.add(Immutables.immutableInternalCacheEntry(dc.get("k2")));
    expected.add(Immutables.immutableInternalCacheEntry(dc.get("k3")));
    expected.add(Immutables.immutableInternalCacheEntry(dc.get("k4")));

    Set actual = new HashSet();
    for (Map.Entry o : dc.entrySet()) actual.add(o);

    assert actual.equals(expected) : "Expected to see keys " + expected + " but only saw " + actual;
  }
Example #24
0
  private void query(Vertex vertex, Iterator<Vertex> path, DataContainer container) {
    if (path.hasNext()) {
      Vertex queryVertex = path.next();
      Vertex neighbor = vertex.getNeighbor(queryVertex.getLabel());
      if (neighbor == null) {
        /* Specified hash character wasn't found, there are no matches
         * for this query. */
        return;
      } else {
        query(neighbor, path, container);
      }
    } else {
      for (Vertex v : vertex.getAllNeighbors()) {
        query(v, path, container);
      }
    }

    if (vertex.hasData()) {
      container.merge(vertex.getData());
    }
  }
  /** {@inheritDoc} */
  @Override
  protected DataExecutionResponse run(
      DataBuilderContext dataBuilderContext,
      DataFlowInstance dataFlowInstance,
      DataDelta dataDelta,
      DataFlow dataFlow,
      DataBuilderFactory builderFactory)
      throws DataBuilderFrameworkException, DataValidationException {
    CompletionService<DataContainer> completionExecutor =
        new ExecutorCompletionService<DataContainer>(executorService);
    ExecutionGraph executionGraph = dataFlow.getExecutionGraph();
    DataSet dataSet =
        dataFlowInstance.getDataSet().accessor().copy(); // Create own copy to work with
    DataSetAccessor dataSetAccessor = DataSet.accessor(dataSet);
    dataSetAccessor.merge(dataDelta);
    Map<String, Data> responseData = Maps.newTreeMap();
    Set<String> activeDataSet = Sets.newHashSet();

    for (Data data : dataDelta.getDelta()) {
      activeDataSet.add(data.getData());
    }
    List<List<DataBuilderMeta>> dependencyHierarchy = executionGraph.getDependencyHierarchy();
    Set<String> newlyGeneratedData = Sets.newHashSet();
    Set<DataBuilderMeta> processedBuilders =
        Collections.synchronizedSet(Sets.<DataBuilderMeta>newHashSet());
    while (true) {
      for (List<DataBuilderMeta> levelBuilders : dependencyHierarchy) {
        List<Future<DataContainer>> dataFutures = Lists.newArrayList();
        for (DataBuilderMeta builderMeta : levelBuilders) {
          if (processedBuilders.contains(builderMeta)) {
            continue;
          }
          // If there is an intersection, means some of it's inputs have changed. Reevaluate
          if (Sets.intersection(builderMeta.getConsumes(), activeDataSet).isEmpty()) {
            continue;
          }
          DataBuilder builder = builderFactory.create(builderMeta.getName());
          if (!dataSetAccessor.checkForData(builder.getDataBuilderMeta().getConsumes())) {
            break; // No need to run others, list is topo sorted
          }
          BuilderRunner builderRunner =
              new BuilderRunner(
                  dataBuilderExecutionListener,
                  dataFlowInstance,
                  builderMeta,
                  dataDelta,
                  responseData,
                  builder,
                  dataBuilderContext,
                  processedBuilders,
                  dataSet);
          Future<DataContainer> future = completionExecutor.submit(builderRunner);
          dataFutures.add(future);
        }

        // Now wait for something to complete.
        int listSize = dataFutures.size();
        for (int i = 0; i < listSize; i++) {
          try {
            DataContainer responseContainer = completionExecutor.take().get();
            Data response = responseContainer.getGeneratedData();
            if (responseContainer.isHasError()) {
              if (null != responseContainer.getValidationException()) {
                throw responseContainer.getValidationException();
              }

              throw responseContainer.getException();
            }
            if (null != response) {
              dataSetAccessor.merge(response);
              responseData.put(response.getData(), response);
              activeDataSet.add(response.getData());
              if (null != dataFlow.getTransients()
                  && !dataFlow.getTransients().contains(response.getData())) {
                newlyGeneratedData.add(response.getData());
              }
            }
          } catch (InterruptedException e) {
            throw new DataBuilderFrameworkException(
                DataBuilderFrameworkException.ErrorCode.BUILDER_EXECUTION_ERROR,
                "Error while waiting for error ",
                e);
          } catch (ExecutionException e) {
            throw new DataBuilderFrameworkException(
                DataBuilderFrameworkException.ErrorCode.BUILDER_EXECUTION_ERROR,
                "Error while waiting for error ",
                e.getCause());
          }
        }
      }
      if (newlyGeneratedData.contains(dataFlow.getTargetData())) {
        // logger.debug("Finished running this instance of the flow. Exiting.");
        break;
      }
      if (newlyGeneratedData.isEmpty()) {
        // logger.debug("Nothing happened in this loop, exiting..");
        break;
      }
      //            StringBuilder stringBuilder = new StringBuilder();
      //            for(String data : newlyGeneratedData) {
      //                stringBuilder.append(data + ", ");
      //            }
      // logger.info("Newly generated: " + stringBuilder);
      activeDataSet.clear();
      activeDataSet.addAll(newlyGeneratedData);
      newlyGeneratedData.clear();
      if (!dataFlow.isLoopingEnabled()) {
        break;
      }
    }
    DataSet finalDataSet = dataSetAccessor.copy(dataFlow.getTransients());
    dataFlowInstance.setDataSet(finalDataSet);
    return new DataExecutionResponse(responseData);
  }
Example #26
0
 @Override
 public TriggerInstance data(String key, Object value, DataType dataType) {
   super.data(key, value, dataType);
   return this;
 }
Example #27
0
 @Override
 public TriggerInstance typedValue(String key, TypedValue value) {
   super.typedValue(key, value);
   return this;
 }
Example #28
0
 @Override
 public TriggerInstance data(Map<String, Object> data) {
   super.data(data);
   return this;
 }
  @EventHandler
  public void onInventoryClick(InventoryClickEvent e) {
    DataContainer dataContainer = plugin.getDataContainer();
    Player player = (Player) e.getWhoClicked();

    String name = ChatColor.stripColor(e.getInventory().getName());

    if (name.equalsIgnoreCase("Title categories")) {
      e.setCancelled(true);
      if (e.getCurrentItem() == null
          || e.getCurrentItem().getType() == Material.AIR
          || !e.getCurrentItem().hasItemMeta()) {
        player.closeInventory();
        return;
      }

      if (e.getCurrentItem().getData() instanceof Wool) {

        // All unlocked titles of player
        if (e.getCurrentItem().getItemMeta().getDisplayName().equalsIgnoreCase("Unlocked")) {
          player.openInventory(constructInventory(plugin, player, null, true));
          return;
        }

        // open Titles in category
        player.openInventory(
            constructInventory(
                plugin,
                player,
                Utils.strip(Utils.setColors(e.getCurrentItem().getItemMeta().getDisplayName())),
                false));
      }
    } else if (name.equalsIgnoreCase("Titles in category")
        || name.equalsIgnoreCase("Unlocked Titles")) {
      e.setCancelled(true);
      if (e.getCurrentItem() == null
          || e.getCurrentItem().getType() == Material.AIR
          || !e.getCurrentItem().hasItemMeta()) {
        player.closeInventory();
        return;
      }

      // back button
      if (e.getCurrentItem().getItemMeta().getDisplayName().equalsIgnoreCase("Back")) {
        player.openInventory(constructInventory(plugin, player, null, false));
        return;
      }

      String category = null;
      String[] split = e.getCurrentItem().getItemMeta().getLore().get(1).split(" ");
      if (split.length == 2) category = split[1];

      if (e.getCurrentItem().getData() instanceof Wool) {
        DyeColor color = ((Wool) e.getCurrentItem().getData()).getColor();
        Title title =
            dataContainer.getTitle(
                Utils.strip(
                    Utils.setColors(
                        e.getCurrentItem().getItemMeta().getDisplayName().toLowerCase())));
        Inventory inv = e.getInventory();
        ItemMeta im = e.getCurrentItem().getItemMeta();
        int slot = e.getSlot();
        if (name.equalsIgnoreCase("Titles in category")) {
          switch (color) {
            case RED:
              // Request title.
              if (player.hasPermission(plugin.makeRequestsPerm)) {
                if (RequestCommands.submitRequest(dataContainer, player, title.getId())) {
                  Utils.sendMsg(
                      player,
                      "Your request for "
                          + ChatColor.ITALIC
                          + title.getName()
                          + ChatColor.RESET
                          + " has been submitted.");
                  handleBlock(inv, im, DyeColor.ORANGE, "Pending", slot);
                } else
                  Utils.sendError(
                      player, "You already have a pending request or that title doesn't exist.");
              } else Utils.sendError(player, "You don't have permission to do that.");
              break;
            case LIME:
              // Disable current title.
              if (player.hasPermission(plugin.setTitlePerm)) {
                if (SetCommands.disableTitle(dataContainer, player)) {
                  Utils.sendMsg(player, "Title disabled.");
                  handleBlock(inv, im, DyeColor.GREEN, "Unlocked", slot);
                } else Utils.sendError(player, "Player doesn't have that title active.");
              } else Utils.sendError(player, "You don't have permission to do that.");
              break;
            case GREEN:
              // Set title as current.
              if (player.hasPermission(plugin.setTitlePerm)) {
                if (SetCommands.setTitle(dataContainer, player, title.getId())) {
                  Utils.sendMsg(
                      player,
                      String.format(
                          "Title set to %s" + title.getName() + "%s.",
                          ChatColor.ITALIC,
                          ChatColor.RESET));
                  handleBlock(inv, im, DyeColor.LIME, "Current", slot);
                  if (category == null) player.closeInventory();
                  else player.openInventory(constructInventory(plugin, player, category, false));

                } else
                  Utils.sendError(player, "Player doesn't own that title or it doesn't exist.");
              } else Utils.sendError(player, "You don't have permission to do that.");
              break;
            case ORANGE:
              // Retract request.
              if (player.hasPermission(plugin.makeRequestsPerm)) {
                if (RequestCommands.retractRequest(dataContainer, player)) {
                  Utils.sendMsg(player, "Your request has successfully been retracted.");
                  handleBlock(inv, im, DyeColor.RED, "Locked", slot);
                } else Utils.sendError(player, "You don't have a pending request.");
              } else Utils.sendError(player, "You don't have permission to do that.");
              break;
          }

        } else if (name.equalsIgnoreCase("Unlocked Titles")) {
          switch (color) {
            case LIME:
              // Disable current title.
              if (player.hasPermission(plugin.setTitlePerm)) {
                if (SetCommands.disableTitle(dataContainer, player)) {
                  Utils.sendMsg(player, "Title disabled.");
                  handleBlock(inv, im, DyeColor.GREEN, "Unlocked", slot);
                } else Utils.sendError(player, "Player doesn't have that title active.");
              } else Utils.sendError(player, "You don't have permission to do that.");
              break;
            case GREEN:
              // Set title as current.
              if (player.hasPermission(plugin.setTitlePerm)) {
                if (SetCommands.setTitle(dataContainer, player, title.getId())) {
                  Utils.sendMsg(
                      player,
                      String.format(
                          "Title set to %s" + title.getName() + "%s.",
                          ChatColor.ITALIC,
                          ChatColor.RESET));
                  handleBlock(inv, im, DyeColor.LIME, "Current", slot);
                  if (category == null) player.closeInventory();
                  else player.openInventory(constructInventory(plugin, player, category, false));

                } else
                  Utils.sendError(player, "Player doesn't own that title or it doesn't exist.");
              } else Utils.sendError(player, "You don't have permission to do that.");
              break;
          }
        }
      }
    }
  }
  @SuppressWarnings("deprecation")
  public static Inventory constructInventory(
      TitlesPlugin plugin, Player player, String cat, boolean owned) {
    DataContainer dataContainer = plugin.getDataContainer();
    Inventory inv = null;
    // if there are titles, construct category inventory
    if (!dataContainer.getTitles().isEmpty()) {
      List<String> categories = GetCommands.getCategories(dataContainer);
      List<ItemStack> clickables = new ArrayList<>();

      // get inventory with categories.
      if (cat == null) {

        if (owned) {
          List<Title> unlocked = dataContainer.getUnlockedTitles(player);
          for (Title title : unlocked) {
            ItemStack is;
            String name = title.getName();
            String description = title.getDescription();
            String status;

            if (dataContainer.getCurrentTitle(player) != null
                && dataContainer.getCurrentTitle(player).equals(title)) {
              is = new ItemStack(Material.WOOL, 1, DyeColor.LIME.getData());
              status = "Current";
            } else {
              is = new ItemStack(Material.WOOL, 1, DyeColor.GREEN.getData());
              status = "Unlocked";
            }
            ItemMeta meta = is.getItemMeta();
            meta.setDisplayName(name);
            meta.setLore(
                Arrays.asList(
                    "Description: " + description,
                    "Category: " + title.getCategory().getName(),
                    "Status: " + status));
            is.setItemMeta(meta);
            clickables.add(is);
          }

          int size = ((clickables.size() / 9) + 1) * 9;
          inv =
              Bukkit.createInventory(
                  null, size, ChatColor.DARK_AQUA + "" + ChatColor.BOLD + "Unlocked Titles");

          for (int i = 0; i < clickables.size(); i++) inv.setItem(i, clickables.get(i));

          // back button
          ItemStack is = new ItemStack(Material.WOOL, 1, DyeColor.GRAY.getData());
          ItemMeta meta = is.getItemMeta();
          meta.setDisplayName("Back");
          is.setItemMeta(meta);
          inv.setItem(inv.getSize() - 1, is);
          return inv;
        }

        for (String category : categories) {
          ItemStack is = new ItemStack(Material.WOOL, 1, DyeColor.GRAY.getData());
          ItemMeta meta = is.getItemMeta();
          meta.setDisplayName(category);
          is.setItemMeta(meta);
          clickables.add(is);
        }
        int size = ((clickables.size() / 9) + 1) * 9;
        inv =
            Bukkit.createInventory(
                null, size, ChatColor.DARK_AQUA + "" + ChatColor.BOLD + "Title categories");

        // get inventory with titles from category.
      } else {
        Category category = dataContainer.getCategory(cat);
        if (category == null) return null;
        List<Title> titles = dataContainer.getTitlesFromCategory(category);
        List<Title> ownedTitles = dataContainer.getUnlockedTitles(player);

        for (Title title : titles) {
          ItemStack is;
          String name = title.getName();
          String description = title.getDescription();
          String status;

          if (ownedTitles.contains(title)) {
            if (dataContainer.getCurrentTitle(player) != null
                && dataContainer.getCurrentTitle(player).equals(title)) {
              is = new ItemStack(Material.WOOL, 1, DyeColor.LIME.getData());
              status = "Current";
            } else {
              is = new ItemStack(Material.WOOL, 1, DyeColor.GREEN.getData());
              status = "Unlocked";
            }
          } else {
            Request request = dataContainer.getRequest(player);
            if (request != null
                && request.getTitle().equals(title)
                && request.getStatus() == RequestStatus.pending) {
              is = new ItemStack(Material.WOOL, 1, DyeColor.ORANGE.getData());
              status = "Pending";
            } else {
              is = new ItemStack(Material.WOOL, 1, DyeColor.RED.getData());
              status = "Locked";
            }
          }

          ItemMeta meta = is.getItemMeta();
          meta.setDisplayName(name);
          meta.setLore(
              Arrays.asList(
                  "Description: " + description,
                  "Category: " + category.getName(),
                  "Status: " + status));
          is.setItemMeta(meta);
          clickables.add(is);
        }
        int size = ((clickables.size() / 9) + 1) * 9;
        inv =
            Bukkit.createInventory(
                null, size, ChatColor.DARK_AQUA + "" + ChatColor.BOLD + "Titles in category");
      }

      for (int i = 0; i < clickables.size(); i++) inv.setItem(i, clickables.get(i));

      // back button
      if (cat != null) {
        ItemStack is = new ItemStack(Material.WOOL, 1, DyeColor.GRAY.getData());
        ItemMeta meta = is.getItemMeta();
        meta.setDisplayName("Back");
        is.setItemMeta(meta);
        inv.setItem(inv.getSize() - 1, is);

        // player's unlocked titles
      } else {
        ItemStack is = new ItemStack(Material.WOOL, 1, DyeColor.GREEN.getData());
        ItemMeta meta = is.getItemMeta();
        meta.setDisplayName("Unlocked");
        is.setItemMeta(meta);
        inv.setItem(inv.getSize() - 1, is);
      }

    } else Utils.sendError(player, "There are no titles yet.");
    return inv;
  }