/*
* Aipo is a groupware program developed by TOWN, Inc.
* Copyright (C) 2004-2015 TOWN, Inc.
* http://www.aipo.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aimluck.eip.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.mail.internet.MimeUtility;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.jetspeed.om.profile.Entry;
import org.apache.jetspeed.om.profile.Portlets;
import org.apache.jetspeed.om.profile.Profile;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.resources.JetspeedResources;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.jetspeed.util.template.JetspeedLink;
import org.apache.jetspeed.util.template.JetspeedLinkFactory;
import org.apache.turbine.services.upload.TurbineUpload;
import org.apache.turbine.util.DynamicURI;
import org.apache.turbine.util.RunData;
import com.aimluck.eip.services.portal.ALPortalApplicationService;
/**
*
*/
public class ALCommonUtils {
/** logger */
private static final JetspeedLogger logger = JetspeedLogFactoryService
.getLogger(ALCommonUtils.class.getName());
/** 乱数生成用アルゴリズム(SHA1) */
public static final String DEF_RANDOM_ALGORITHM = "SHA1PRNG";
/** 乱数生成用アルゴリズム(生成するバイト配列の長さ) */
public static final int DEF_RANDOM_LENGTH = 16;
/** 乱数生成機保持用 */
private static SecureRandom random = getSecureRandom();
private static String CACHE_BUST = null;
public static String escapeXML(String string) {
return StringEscapeUtils.escapeXml(string);
}
public static String escapeXML(DynamicURI uri) {
return StringEscapeUtils.escapeXml(uri.toString());
}
public static String getCloudUrl() {
return JetspeedResources.getString("aipo.cloud.url");
}
/**
* * 長いアルファベットのテキストを自動的に折り返すヘルパー
*
* @subpackage helper
* @param string
* $text
* @param int $step
* @return string
*/
public static String replaceToAutoCRString(String str) {
if (str == null || "".equals(str)) {
return "";
}
StringBuffer res = new StringBuffer("");
int step = 4;
int size = str.length();
int count = size / step;
int j;
for (int i = 0; i < count; i++) {
j = i * step;
res.append(str.substring(j, j + step)).append("<wbr/>");
}
if (count * step < size) {
res.append(str.substring(count * step));
}
return res.toString();
}
public static int getMaxFileSize() {
return getMaxFileSize("MB");
}
public static int getMaxFileSize(String unit) {
int size = TurbineUpload.getSizeMax();
if (unit.equals("MB")) {
size = size / 1024 / 1024;
} else if (unit.equals("KB")) {
size = size / 1024;
}
return size;
}
/**
* * 長いアルファベットのテキストを自動的に折り返すヘルパー
*
* @subpackage helper
* @param string
* $text
* @param int $step
* @return string
*/
public static String replaceToAutoCRChild(String str) {
if (str == null || "".equals(str)) {
return "";
}
StringBuffer res = null;
String head, body, tail;
int findex = str.indexOf("&");
int lindex = str.indexOf(";");
if ((findex == -1) && (lindex == -1)) {
return replaceToAutoCRString(str);
} else if (lindex != -1 && (findex == -1 || findex > lindex)) {
// ";"のみ含まれる場合
head = str.substring(0, lindex);
body = str.substring(lindex, lindex + 1);
tail = str.substring(lindex + 1);
res = new StringBuffer();
res.append(replaceToAutoCRString(head));
res.append(body);
res.append(replaceToAutoCR(tail));
} else if (findex != -1 && lindex == -1) {
// "&"のみ含まれる場合
head = str.substring(0, findex);
body = str.substring(findex, findex + 1);
tail = str.substring(findex + 1);
res = new StringBuffer();
res.append(replaceToAutoCRString(head));
res.append(body);
res.append(replaceToAutoCR(tail));
} else {
head = str.substring(0, findex);
body = str.substring(findex, lindex + 1);
tail = str.substring(lindex + 1);
res = new StringBuffer();
res.append(replaceToAutoCRString(head));
res.append(body);
res.append(replaceToAutoCR(tail));
}
return res.toString();
}
/**
* * 長いアルファベットのテキストを自動的に折り返すヘルパー
*
* @subpackage helper
* @param string
* $text
* @param int $step
* @return string
*/
public static String replaceToAutoCR(String str) {
if (str == null || "".equals(str)) {
return "";
}
StringBuffer res = null;
String head, body, tail;
int findex = str.indexOf("<");
int lindex = str.indexOf(">");
if ((findex == -1) && (lindex == -1)) {
return replaceToAutoCRChild(str);
} else if (findex == -1 || findex > lindex) {
// ">"のみ含まれる場合
head = str.substring(0, lindex);
body = str.substring(lindex, lindex + 1);
tail = str.substring(lindex + 1);
res = new StringBuffer();
res.append(replaceToAutoCRChild(head));
res.append(body);
res.append(replaceToAutoCR(tail));
} else if (lindex == -1) {
// "<"のみ含まれる場合
head = str.substring(0, findex);
body = str.substring(findex, findex + 1);
tail = str.substring(findex + 1);
res = new StringBuffer();
res.append(replaceToAutoCRChild(head));
res.append(body);
res.append(replaceToAutoCR(tail));
} else {
head = str.substring(0, findex);
body = str.substring(findex, lindex + 1);
tail = str.substring(lindex + 1);
res = new StringBuffer();
res.append(replaceToAutoCRChild(head));
res.append(body);
res.append(replaceToAutoCR(tail));
}
return res.toString();
}
/**
* 第二引数で指定した長さで、第一引数の文字列を丸める。
*
* @param src
* 元の文字列
* @param length
* 丸めの長さ
* @return ●処理後の文字列
*/
public static String compressString(String src, int length) {
if (src == null || src.length() == 0 || length <= 0) {
return src;
}
String subject;
if (src.length() > length) {
subject = src.substring(0, length);
subject += "・・・";
} else {
subject = src;
}
return subject;
}
/**
* ランダムなセキュリティIDを生成する。
*
* @return string ランダムIDの文字列型
*/
public static String getSecureRandomString() {
String res = null;
MessageDigest md;
try {
if (null == random) {
return null;
}
byte b[] = new byte[DEF_RANDOM_LENGTH];
random.nextBytes(b);
md = MessageDigest.getInstance("SHA-1");
md.update(b);
StringBuffer sb = new StringBuffer();
for (byte _b : b) {
sb.append(String.format("%02x", _b));
}
res = sb.toString();
} catch (Exception e) {
logger.error("ALCommonUtils.getSecureRandomString", e);
return null;
}
return res;
}
/**
* セキュリティID生成用のSecureRandomを生成します。
*
* @return random セキュリティID生成用のSecureRandom
*/
public static SecureRandom getSecureRandom() {
SecureRandom random = null;
try {
random = SecureRandom.getInstance(DEF_RANDOM_ALGORITHM);
byte seed[] = random.generateSeed(DEF_RANDOM_LENGTH);
random.setSeed(seed);
} catch (Exception e) {
logger.error("ALCommonUtils.getSecureRandom", e);
return null;
}
return random;
}
/**
* 画像表示用の整数をランダムで生成します。
*
* @return
*/
public int getImageRandomNumber() {
SecureRandom random = new SecureRandom();
return (random.nextInt() * 100);
}
/**
* URL文字列にスキーマ部分が含まれていなかった場合、先頭に付加した物を返します
*
* @param url
* @return
*/
public static String normalizeURL(String url) {
String res = url;
if (!res.contains("://")) {
res = "http://" + res;
}
return res;
}
/**
* 指定したエントリー名を持つ個人設定ページに含まれるポートレットへの URI を取得する.
*
* @param rundata
* @param portletEntryName
* PSML ファイルに記述されているタグ entry の要素 parent
* @return
*/
public static DynamicURI getPortletURIinPersonalConfigPane(RunData rundata,
String portletEntryName) {
try {
Portlets portlets =
((JetspeedRunData) rundata).getProfile().getDocument().getPortlets();
if (portlets == null) {
return null;
}
Portlets[] portletList = portlets.getPortletsArray();
if (portletList == null) {
return null;
}
int length = portletList.length;
for (int i = 0; i < length; i++) {
Entry[] entries = portletList[i].getEntriesArray();
if (entries == null || entries.length <= 0) {
continue;
}
int ent_length = entries.length;
for (int j = 0; j < ent_length; j++) {
if (entries[j].getParent().equals(portletEntryName)) {
JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
DynamicURI duri =
jsLink.getLink(
JetspeedLink.CURRENT,
null,
null,
JetspeedLink.CURRENT,
null);
duri =
duri
.addPathInfo(
JetspeedResources.PATH_PANEID_KEY,
portletList[i].getId() + "," + entries[j].getId())
.addQueryData(
JetspeedResources.PATH_ACTION_KEY,
"controls.Restore");
return duri;
}
}
}
} catch (Exception ex) {
logger.error("ALCommonUtils.getPortletURIinPersonalConfigPane", ex);
return null;
}
return null;
}
/**
* 指定したエントリー名を持つ個人設定ページに含まれるポートレットへの URI を取得する.
*
* @param rundata
* @param portletEntryName
* PSML ファイルに記述されているタグ entry の要素 parent
* @return
*/
// これで本当に合ってるかはよくわかってない
public static DynamicURI getPortletURIinPersonalConfigPeid(RunData rundata,
String portletEntryName) {
try {
Profile profile = ((JetspeedRunData) rundata).getProfile();
if (profile == null) {
return null;
}
Portlets portlets = profile.getDocument().getPortlets();
if (portlets == null) {
return null;
}
Portlets[] portletList = portlets.getPortletsArray();
if (portletList == null) {
return null;
}
int length = portletList.length;
for (int i = 0; i < length; i++) {
Entry[] entries = portletList[i].getEntriesArray();
if (entries == null || entries.length <= 0) {
continue;
}
int ent_length = entries.length;
for (int j = 0; j < ent_length; j++) {
if (entries[j].getParent().equals(portletEntryName)) {
JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
DynamicURI duri =
jsLink.getLink(
JetspeedLink.CURRENT,
null,
null,
JetspeedLink.CURRENT,
null);
duri =
duri.addPathInfo(JetspeedResources.PATH_PORTLETID_KEY, entries[j]
.getId());
return duri;
}
}
}
} catch (Exception ex) {
logger.error("ALCommonUtils.getPortletURIinPersonalConfigPeid", ex);
return null;
}
return null;
}
public static String getCacheBust() {
if (CACHE_BUST == null) {
File file = new File(JetspeedResources.getString("aipo.cached.file"));
long lastModified = file.lastModified();
CACHE_BUST = String.valueOf(lastModified);
}
return CACHE_BUST;
}
public static boolean isAndroidBrowser(RunData rundata) {
return ALEipUtils.isAndroidBrowser(rundata);
}
public static boolean isAndroid2Browser(RunData rundata) {
return ALEipUtils.isAndroid2Browser(rundata);
}
/**
* 指定したポートレットが利用可能かどうかを返す
*
* @param portletName
*
* @return
*/
public static boolean isActive(String portletName) {
return ALPortalApplicationService.isActive(portletName);
}
// :HACK
// can't be called...
// public static String getl10nFormat(String key, Object... values) {
// return ALLocalizationUtils.getl10nFormat(key, values);
// }
public static String getl10nFormat1(String key, Object values) {
return ALLocalizationUtils.getl10nFormat(key, values);
}
public static String replaceToTelLink(String tel) {
if (!StringUtils.isEmpty(tel)) {
return tel.replaceAll("-", "");
} else {
return "";
}
}
public static long getCurrentTime() {
return new Date().getTime();
}
public static boolean isFileUploadable(RunData rundata) {
return ALEipUtils.isFileUploadable(rundata);
}
public static byte[] encrypt(String key, String text) {
try {
SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, sksSpec);
return cipher.doFinal(text.getBytes());
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
return null;
}
public static String decrypt(String key, byte[] encrypted) {
try {
SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, sksSpec);
return new String(cipher.doFinal(encrypted));
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
return null;
}
public static String encodeBase64(byte[] data) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStream os = null;
try {
os = MimeUtility.encode(bos, "base64");
os.write(data);
} catch (Throwable t) {
logger.error(t.getMessage(), t);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
try {
return bos.toString("iso-8859-1");
} catch (UnsupportedEncodingException e) {
logger.error(e.getMessage(), e);
}
return null;
}
public static byte[] decodeBase64(String base64) {
byte[] buf = new byte[1024];
ByteArrayOutputStream os = new ByteArrayOutputStream();
InputStream is = null;
try {
is =
MimeUtility.decode(
new ByteArrayInputStream(base64.getBytes()),
"base64");
for (int len = -1; (len = is.read(buf)) != -1;) {
os.write(buf, 0, len);
}
} catch (Throwable t) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
return os.toByteArray();
}
}