<commit_before>/*
 * Copyright 2011, The gwtquery team.
 * 
 * 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.
 */
package com.google.gwt.query.client;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.query.client.js.JsCache;
import com.google.gwt.query.client.js.JsUtils;

/**
 * JSO for accessing Javascript objective literals used by GwtQuery functions.
 */
public class Properties extends JavaScriptObject {
  
  public static Properties create() {
    return JsCache.create().cast();
  }
  
  public static Properties create(String properties) {
    if (properties != null && !properties.isEmpty()) {
      String p = wrapPropertiesString(properties);
      try {
        return JsUtils.parseJSON(p);
      } catch (Exception e) {
        System.err.println("Error creating Properties: \n> " + properties  + "\n< " + p + "\n" + e.getMessage());
      }
    }
    return create();
  }

  public static String wrapPropertiesString(String s) {
    String ret = s //
        .replaceAll("\\s*/\\*[\\s\\S]*?\\*/\\s*", "") // Remove comments
        .replaceAll("([:\\)\\(,;}{'\"])\\s+" , "$1") // Remove spaces
        .replaceAll("\\s+([:\\)\\(,;}{'\"])" , "$1") // Remove spaces
        .replaceFirst("^[\\(]+(.*)[\\)]+$", "$1") // Remove ()
        .replaceAll("\\([\"']([^\\)]+)[\"']\\)" , "($1)") // Remove quotes
        .replaceAll("[;,]+([\\w-\\$]+):", ";$1:") // Change comma by semicolon
        .replaceAll("([^,;])([\\]}])", "$1;$2") // Put control semicolon used below
        .replaceAll(":\\s*[\"']?([^;\\{\\}\\[\\]\"']*)[\"']?\\s*([;,]+|$)", ":\"$1\";") // put quotes to all values (even empty)
        .replaceAll("[;,]+([\\w-]+):", ";$1:") // Change semicolon by comma
        .replaceAll("(^|[^\\w-\\$'])([\\w-\\$]+):(['\"\\[{])", "$1\"$2\":$3") // quote keys
        .replaceAll("(^|[^\\w-\\$'])([\\w-\\$]+):(['\"\\[{])", "$1\"$2\":$3") // quote keys second pass
        .replaceAll("(|[\\[\\]\\{\\},\\(])'([^']*)'", "$1\"$2\"") // Replace single-quote by double-quote
        .replaceAll(";([^:]+):", ",$1:") // change semicolon
        .replaceAll(";([^:]+):", ",$1:") // change semicolon second pass
        .replaceAll(":\"(-?\\d[\\d\\.]*|null|false|true)\"[;,]", ":$1,") // numbers do not need quote
        .replaceAll("[;,]+([\\]\\}]|$)", "$1") // remove endings 
        ;
    ret = ret.matches("(^[\\[\\{].*[\\]\\}]$)") ? ret : "{" + ret + "}";
    return ret;
  }
  
  protected Properties() {
  }

  public final Properties $$(String key, String value) {
    set(key, value);
    return this;
  }

  private JsCache c() {
    return this.<JsCache>cast();
  }

  public final native Properties cloneProps() /*-{
    var props = {};
    for(p in this) {
      props[p] =  this[p];
    }
    return props;
  }-*/;

  public final boolean defined(Object name) {
    return c().exists(String.valueOf(name));
  }

  public final <T> T get(Object name) {
    return c().get(String.valueOf(name));
  }

  public final boolean getBoolean(Object name) {
    return c().getBoolean(String.valueOf(name));
  }

  public final float getFloat(Object name) {
    return c().getFloat(String.valueOf(name));
  }

  public final int getInt(Object name) {
    return c().getInt(String.valueOf(name));
  }
  
  public final String getStr(Object name) {
    return c().getString(String.valueOf(name));
  }
  
  public final Object getObject(Object name) {
    return c().get(String.valueOf(name));
  }
  
  public final <T extends JavaScriptObject> T getJavaScriptObject(Object name) {
    return c().getJavaScriptObject(String.valueOf(name));
  }

  public final JsArrayMixed getArray(Object name) {
    return c().getArray(String.valueOf(name));
  }
  
  public final String[] keys() {
    return c().keys();
  }
  
  public final <T> void remove(T name) {
    c().delete(String.valueOf(name));
  }
  
  public final <T> void set(T name, Object val) {
    c().put(String.valueOf(name), val);
  }
  
  public final String tostring() {
    return toJsonString();
  }
  
  public final String toJsonString() {
    String ret = "";
    
    for (String k : keys()){
      String ky = k.matches("\\d+") ? k : "\"" + k + "\"";
      JsCache o = getArray(k).cast();
      if (o != null) {
        ret += ky + ":[";
        for (int i = 0, l = o.length(); i < l ; i++) {
          Properties p = o.<JsCache>cast().getJavaScriptObject(i);
          if (p != null) {<commit_msg>properties toJsonString should not export gwt hashCodes. Fixes tests<commit_after>/*
 * Copyright 2011, The gwtquery team.
 * 
 * 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.
 */
package com.google.gwt.query.client;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.query.client.js.JsCache;
import com.google.gwt.query.client.js.JsUtils;

/**
 * JSO for accessing Javascript objective literals used by GwtQuery functions.
 */
public class Properties extends JavaScriptObject {
  
  public static Properties create() {
    return JsCache.create().cast();
  }
  
  public static Properties create(String properties) {
    if (properties != null && !properties.isEmpty()) {
      String p = wrapPropertiesString(properties);
      try {
        return JsUtils.parseJSON(p);
      } catch (Exception e) {
        System.err.println("Error creating Properties: \n> " + properties  + "\n< " + p + "\n" + e.getMessage());
      }
    }
    return create();
  }

  public static String wrapPropertiesString(String s) {
    String ret = s //
        .replaceAll("\\s*/\\*[\\s\\S]*?\\*/\\s*", "") // Remove comments
        .replaceAll("([:\\)\\(,;}{'\"])\\s+" , "$1") // Remove spaces
        .replaceAll("\\s+([:\\)\\(,;}{'\"])" , "$1") // Remove spaces
        .replaceFirst("^[\\(]+(.*)[\\)]+$", "$1") // Remove ()
        .replaceAll("\\([\"']([^\\)]+)[\"']\\)" , "($1)") // Remove quotes
        .replaceAll("[;,]+([\\w-\\$]+):", ";$1:") // Change comma by semicolon
        .replaceAll("([^,;])([\\]}])", "$1;$2") // Put control semicolon used below
        .replaceAll(":\\s*[\"']?([^;\\{\\}\\[\\]\"']*)[\"']?\\s*([;,]+|$)", ":\"$1\";") // put quotes to all values (even empty)
        .replaceAll("[;,]+([\\w-]+):", ";$1:") // Change semicolon by comma
        .replaceAll("(^|[^\\w-\\$'])([\\w-\\$]+):(['\"\\[{])", "$1\"$2\":$3") // quote keys
        .replaceAll("(^|[^\\w-\\$'])([\\w-\\$]+):(['\"\\[{])", "$1\"$2\":$3") // quote keys second pass
        .replaceAll("(|[\\[\\]\\{\\},\\(])'([^']*)'", "$1\"$2\"") // Replace single-quote by double-quote
        .replaceAll(";([^:]+):", ",$1:") // change semicolon
        .replaceAll(";([^:]+):", ",$1:") // change semicolon second pass
        .replaceAll(":\"(-?\\d[\\d\\.]*|null|false|true)\"[;,]", ":$1,") // numbers do not need quote
        .replaceAll("[;,]+([\\]\\}]|$)", "$1") // remove endings 
        ;
    ret = ret.matches("(^[\\[\\{].*[\\]\\}]$)") ? ret : "{" + ret + "}";
    return ret;
  }
  
  protected Properties() {
  }

  public final Properties $$(String key, String value) {
    set(key, value);
    return this;
  }

  private JsCache c() {
    return this.<JsCache>cast();
  }

  public final native Properties cloneProps() /*-{
    var props = {};
    for(p in this) {
      props[p] =  this[p];
    }
    return props;
  }-*/;

  public final boolean defined(Object name) {
    return c().exists(String.valueOf(name));
  }

  public final <T> T get(Object name) {
    return c().get(String.valueOf(name));
  }

  public final boolean getBoolean(Object name) {
    return c().getBoolean(String.valueOf(name));
  }

  public final float getFloat(Object name) {
    return c().getFloat(String.valueOf(name));
  }

  public final int getInt(Object name) {
    return c().getInt(String.valueOf(name));
  }
  
  public final String getStr(Object name) {
    return c().getString(String.valueOf(name));
  }
  
  public final Object getObject(Object name) {
    return c().get(String.valueOf(name));
  }
  
  public final <T extends JavaScriptObject> T getJavaScriptObject(Object name) {
    return c().getJavaScriptObject(String.valueOf(name));
  }

  public final JsArrayMixed getArray(Object name) {
    return c().getArray(String.valueOf(name));
  }
  
  public final String[] keys() {
    return c().keys();
  }
  
  public final <T> void remove(T name) {
    c().delete(String.valueOf(name));
  }
  
  public final <T> void set(T name, Object val) {
    c().put(String.valueOf(name), val);
  }
  
  public final String tostring() {
    return toJsonString();
  }
  
  public final String toJsonString() {
    String ret = "";
    
    for (String k : keys()){
      String ky = k.matches("\\d+") ? k : "\"" + k + "\"";
      // We do not have to restore gwt hashCodes.  
      if (k.equals("$H")) {
        continue;
      }
      JsCache o = getArray(k).cast();
      if (o != null) {
        ret += ky + ":[";
        for (int i = 0, l = o.length(); i < l ; i++) {
          Properties p = o.<JsCache>cast().getJavaScriptObject(i);
          if (p != null) {
{'fraction_non_alphanumeric': 0.21954125707476915, 'fraction_numerical': 0.005957700327673518, 'mean_word_length': 2.724852071005917, 'pattern_counts': {'":': 14, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2278097', 'n_tokens_mistral': 3375, 'n_tokens_neox': 3276, 'n_words': 833}