LyoKLyoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCiAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCiAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCiAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqLwpwYWNrYWdlIG9yZy5hcGFjaGUuY29tbW9ucy50ZXh0Lm5hbWVzOwoKaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwoKaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sYW5nMy5TdHJpbmdVdGlsczsKCi8qKgogKiA8cD5BIHBhcnNlciBjYXBhYmxlIG9mIHBhcnNpbmcgbmFtZSBwYXJ0cyBvdXQgb2YgYSBzaW5nbGUgc3RyaW5nLjwvcD4KICoKICogPHA+VGhlIGNvZGUgd29ya3MgYnkgYmFzaWNhbGx5IGFwcGx5aW5nIHNldmVyYWwgUmVnZXhlcyBpbiBhIGNlcnRhaW4gb3JkZXIKICogYW5kIHJlbW92aW5nIChjaG9wcGluZykgdG9rZW5zIG9mZiB0aGUgb3JpZ2luYWwgc3RyaW5nLiBUaGUgcGFyc2VyIGNvbnN1bWVzCiAqIHRoZSB0b2tlbnMgZHVyaW5nIGl0cyBjcmVhdGlvbi48L3A+CiAqCiAqIDx1bD4KICogPGxpPkouIFdhbHRlciBXZWF0aGVybWFuIDwvbGk+CiAqIDxsaT5kZSBsYSBDcnV6LCBBbmEgTS48L2xpPgogKiA8bGk+SmFtZXMgQy4gKCdKaW1teScpIE8nRGVsbCwgSnIuPC9saT4KICogPC91bD4KICoKICogPHA+YW5kIHBhcnNlcyBvdXQgdGhlOjwvcD4KICoKICogPHVsPgogKiA8bGk+bGVhZGluZyBpbml0aWFsIChMaWtlICJKLiIgaW4gIkouIFdhbHRlciBXZWF0aGVybWFuIik8L2xpPgogKiA8bGk+Zmlyc3QgbmFtZSAob3IgZmlyc3QgaW5pdGlhbCBpbiBhIG5hbWUgbGlrZSAnUi4gQ3J1bWInKTwvbGk+CiAqIDxsaT5uaWNrbmFtZXMgKGxpa2UgIkppbW15IiBpbiAiSmFtZXMgQy4gKCdKaW1teScpIE8nRGVsbCwgSnIuIik8L2xpPgogKiA8bGk+bWlkZGxlIG5hbWVzPC9saT4KICogPGxpPmxhc3QgbmFtZSAoaW5jbHVkaW5nIGNvbXBvdW5kIG9uZXMgbGlrZSAidmFuIGRlciBTYXInIGFuZCAiT3J0ZWdhIHkgR2Fzc2V0IiksIGFuZDwvbGk+CiAqIDxsaT5zdWZmaXggKGxpa2UgJ0pyLicsICdJSUknKTwvbGk+CiAqIDwvdWw+CiAqCiAqIDxwcmU+CiAqIE5hbWUgbmFtZSA9IG5ldyBOYW1lKCJT6XJnaW8gVmllaXJhIGRlIE1lbGxvIik7CiAqIEh1bWFuTmFtZVBhcnNlciBwYXJzZXIgPSBuZXcgSHVtYW5OYW1lUGFyc2VyKG5hbWUpOwogKiBTdHJpbmcgZmlyc3ROYW1lID0gcGFyc2VyLmdldEZpcnN0KCk7CiAqIFN0cmluZyBuaWNrbmFtZSA9IHBhcnNlci5nZXROaWNrbmFtZSgpOwogKiAvLyAuLi4KICogPC9wcmU+CiAqCiAqIDxwPlRoZSBvcmlnaW5hbCBjb2RlIHdhcyB3cml0dGVuIGluIDxhIGhyZWY9Imh0dHA6Ly9qYXNvbnByaWVtLmNvbS9odW1hbi1uYW1lLXBhcnNlIj5QSFA8L2E+CiAqIGFuZCBwb3J0ZWQgdG8gPGEgaHJlZj0iaHR0cDovL3R1cGlsYWJzLmdpdGh1Yi5pby9IdW1hbk5hbWVQYXJzZXIuamF2YS8iPkphdmE8L2E+LjwvcD4KICoKICogPHA+VGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBiYXNlZCBvbiB0aGUgSmF2YSBpbXBsZW1lbnRhdGlvbiwgd2l0aCBhZGRpdGlvbnMKICogc3VnZ2VzdGVkIGluIDxhIGhyZWY9Imh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvU0FOREJPWC00ODciPlNBTkRCT1gtNDg3PC9hPi48L3A+CiAqCiAqIDxwPlRoaXMgY2xhc3MgaXMgaW1tdXRhYmxlLjwvcD4KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBIdW1hbk5hbWVQYXJzZXIgewoKICAgIC8qKgogICAgICogU3VmZml4ZXMgZm91bmQuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgTGlzdDxTdHJpbmc+IHN1ZmZpeGVzOwogICAgLyoqCiAgICAgKiBQcmVmaXhlcyBmb3VuZC4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFN0cmluZz4gcHJlZml4ZXM7CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgcGFyc2VyIGdpdmVuIGEgc3RyaW5nIG5hbWUuCiAgICAgKi8KICAgIHB1YmxpYyBIdW1hbk5hbWVQYXJzZXIoKSB7CiAgICAgICAgLy8gVE9ETyBtYWtlIHRoaXMgY29uZmlndXJhYmxlCiAgICAgICAgdGhpcy5zdWZmaXhlcyA9IEFycmF5cy5hc0xpc3QoCiAgICAgICAgICAgICAgICAiZXNxIiwgImVzcXVpcmUiLCAianIiLAogICAgICAgICAgICAgICAgInNyIiwgIjIiLCAiaWkiLCAiaWlpIiwgIml2Iik7CiAgICAgICAgdGhpcy5wcmVmaXhlcyA9IEFycmF5cy5hc0xpc3QoCiAgICAgICAgICAgICAgICAgICAgImJhciIsICJiZW4iLCAiYmluIiwgImRhIiwgImRhbCIsCiAgICAgICAgICAgICAgICAgICAgImRlIGxhIiwgImRlIiwgImRlbCIsICJkZXIiLCAiZGkiLCAiaWJuIiwgImxhIiwgImxlIiwKICAgICAgICAgICAgICAgICAgICAic2FuIiwgInN0IiwgInN0ZSIsICJ2YW4iLCAidmFuIGRlciIsICJ2YW4gZGVuIiwgInZlbCIsCiAgICAgICAgICAgICAgICAgICAgInZvbiIgKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN1bWVzIHRoZSBzdHJpbmcgYW5kIGNyZWF0ZXMgdGhlIG5hbWUgcGFydHMuCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgdG8gcGFyc2UuIE11c3Qgbm90IGJlIG51bGwuCiAgICAgKiBAdGhyb3dzIE5hbWVQYXJzZUV4Y2VwdGlvbiBpZiB0aGUgcGFyc2VyIGZhaWxzIHRvIHJldHJpZXZlIHRoZSBuYW1lIHBhcnRzLgogICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBuYW1lIGlzIG51bGwuCiAgICAgKi8KICAgIHB1YmxpYyBOYW1lIHBhcnNlKFN0cmluZyBuYW1lKSB7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChuYW1lLCAiUGFyYW1ldGVyICduYW1lJyBtdXN0IG5vdCBiZSBudWxsLiIpOwoKICAgICAgICBOYW1lU3RyaW5nIG5hbWVTdHJpbmcgPSBuZXcgTmFtZVN0cmluZyhuYW1lKTsKICAgICAgICAvLyBUT0RPIGNvbXBpbGUgcmVnZXhlcyBvbmx5IG9uY2Ugd2hlbiB0aGUgcGFyc2VyIGlzIGNyZWF0ZWQKICAgICAgICBTdHJpbmcgc3VmZml4ZXMgPSBTdHJpbmdVdGlscy5qb2luKHRoaXMuc3VmZml4ZXMsICJcXC4qfCIpICsgIlxcLioiOwogICAgICAgIFN0cmluZyBwcmVmaXhlcyA9IFN0cmluZ1V0aWxzLmpvaW4odGhpcy5wcmVmaXhlcywgIiB8IikgKyAiICI7CgogICAgICAgIC8vIFRoZSByZWdleCB1c2UgaXMgYSBiaXQgdHJpY2t5LiAgKkV2ZXJ5dGhpbmcqIG1hdGNoZWQgYnkgdGhlIHJlZ2V4IHdpbGwgYmUgcmVwbGFjZWQsCiAgICAgICAgLy8gYnV0IHlvdSBjYW4gc2VsZWN0IGEgcGFydGljdWxhciBwYXJlbnRoZXNpemVkIHN1Ym1hdGNoIHRvIGJlIHJldHVybmVkLgogICAgICAgIC8vIEFsc28sIG5vdGUgdGhhdCBlYWNoIHJlZ2V4IHJlcXVyZXMgdGhhdCB0aGUgcHJlY2VkaW5nIG9uZXMgaGF2ZSBiZWVuIHJ1biwgYW5kIG1hdGNoZXMgY2hvcHBlZCBvdXQuCiAgICAgICAgLy8gbmFtZXMgdGhhdCBzdGFydHMgb3IgZW5kIHcvIGFuIGFwb3N0cm9waGUgYnJlYWsgdGhpcwogICAgICAgIFN0cmluZyBuaWNrbmFtZXNSZWdleCA9ICIoP2kpICgnfFxcXCJ8XFwoXFxcIionKikoLis/KSgnfFxcXCJ8XFxcIionKlxcKSkgIjsKICAgICAgICBTdHJpbmcgc3VmZml4UmVnZXggPSAiKD9pKSwqICooKCIgKyBzdWZmaXhlcyArICIpJCkiOwogICAgICAgIFN0cmluZyBsYXN0UmVnZXggPSAiKD9pKSg/IV4pXFxiKFteIF0rIHkgfCIgKyBwcmVmaXhlcyArICIpKlteIF0rJCI7CiAgICAgICAgLy8gbm90ZSB0aGUgbG9va2FoZWFkLCB3aGljaCBpc24ndCByZXR1cm5lZCBvciByZXBsYWNlZAogICAgICAgIFN0cmluZyBsZWFkaW5nSW5pdFJlZ2V4ID0gIig/aSkoXiguXFwuKikoPz0gXFxwe0x9ezJ9KSkiOwogICAgICAgIFN0cmluZyBmaXJzdFJlZ2V4ID0gIig/aSleKFteIF0rKSI7CgogICAgICAgIC8vIGdldCBuaWNrbmFtZSwgaWYgdGhlcmUgaXMgb25lCiAgICAgICAgU3RyaW5nIG5pY2tuYW1lID0gbmFtZVN0cmluZy5jaG9wV2l0aFJlZ2V4KG5pY2tuYW1lc1JlZ2V4LCAyKTsKCiAgICAgICAgLy8gZ2V0IHN1ZmZpeCwgaWYgdGhlcmUgaXMgb25lCiAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IG5hbWVTdHJpbmcuY2hvcFdpdGhSZWdleChzdWZmaXhSZWdleCwgMSk7CgogICAgICAgIC8vIGZsaXAgdGhlIGJlZm9yZS1jb21tYSBhbmQgYWZ0ZXItY29tbWEgcGFydHMgb2YgdGhlIG5hbWUKICAgICAgICBuYW1lU3RyaW5nLmZsaXAoIiwiKTsKCiAgICAgICAgLy8gZ2V0IHRoZSBsYXN0IG5hbWUKICAgICAgICBTdHJpbmcgbGFzdCA9IG5hbWVTdHJpbmcuY2hvcFdpdGhSZWdleChsYXN0UmVnZXgsIDApOwoKICAgICAgICAvLyBnZXQgdGhlIGZpcnN0IGluaXRpYWwsIGlmIHRoZXJlIGlzIG9uZQogICAgICAgIFN0cmluZyBsZWFkaW5nSW5pdCA9IG5hbWVTdHJpbmcuY2hvcFdpdGhSZWdleChsZWFkaW5nSW5pdFJlZ2V4LCAxKTsKCiAgICAgICAgLy8gZ2V0IHRoZSBmaXJzdCBuYW1lCiAgICAgICAgU3RyaW5nIGZpcnN0ID0gbmFtZVN0cmluZy5jaG9wV2l0aFJlZ2V4KGZpcnN0UmVnZXgsIDApOwogICAgICAgIGlmIChTdHJpbmdVdGlscy5pc0JsYW5rKGZpcnN0KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgTmFtZVBhcnNlRXhjZXB0aW9uKCJDb3VsZG4ndCBmaW5kIGEgZmlyc3QgbmFtZSBpbiAneyIgKyBuYW1lU3RyaW5nLmdldFdyYXBwZWRTdHJpbmcoKSArICJ9JyIpOwogICAgICAgIH0KCiAgICAgICAgLy8gaWYgYW55dGhpbmcncyBsZWZ0LCB0aGF0J3MgdGhlIG1pZGRsZSBuYW1lCiAgICAgICAgU3RyaW5nIG1pZGRsZSA9IG5hbWVTdHJpbmcuZ2V0V3JhcHBlZFN0cmluZygpOwogICAgICAgIAogICAgICAgIHJldHVybiBuZXcgTmFtZShsZWFkaW5nSW5pdCwgZmlyc3QsIG5pY2tuYW1lLCBtaWRkbGUsIGxhc3QsIHN1ZmZpeCk7CiAgICB9Cgp9Cg==