При генерации pdf по форме (без использования собственного pdf-шаблона формы) Orbeon корректно обрабатывает правило @media, поэтому управлять стилем генерируемой pdf-ки можно с помощью css, устанавливая различные стили для @media screen и @media print.
barbitoff programmer`s blog
Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)
пятница, 14 сентября 2012 г.
четверг, 13 сентября 2012 г.
Netbeans 7.2: перемещение проектов между группами проектов
Группы проектов - отличная идея для IDE, но в NetBeans реализация пока что сыровата. Например, для того, чтобы переместить проект из одной группы в другую нужно его закрыть, переключиться в необходимую группу, и открыть его, находясь в ней.
Переключение между группами также далеко от идеала юзабилити - только через контекстное меню окна "Проекты".
понедельник, 10 сентября 2012 г.
Xalan: двойной CR в CDATA-секциях
Наткнулся на баг в библиотеке Xalan (являющейся в моем случае реализацией по-умолчанию javax.xml.transform.TransformerFactory): при сериализации в Windows XML-документа с CDATA-секциями переводы строки в этих секциях представляются последовательностями CR-CR-LF вместо CR-LF. В баг трекере апача соответствующая заявка лежит уже давным-давно без ответа: https://issues.apache.org/jira/browse/XALANJ-2547. Выход - например, заменять вручную в полученной строке "\r\r\n" на "\r\n":
public static String domToString(Document dom) throws TransformerException
{
Source source = new DOMSource(dom);
StringWriter stringWriter = new StringWriter();
Result result = new StreamResult(stringWriter);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.transform(source, result);
return stringWriter.getBuffer().toString().replace("\r\r\n", "\r\n");
}
пятница, 7 сентября 2012 г.
Ant: выполнение действий над каждым файлом из набора
Задача:
В билдфайле ant над каждым файлом из набора (заданного с помощью <fileset/>) выполнить некоторое действие или последовательность действий.
Решение:
Один из вариантов - воспользоваться библиотекой Ant-Contrib (скачать её, а также почитать документацию можно тут: http://ant-contrib.sourceforge.net/, я использовал версию 0.6). Она предоставляет задачу <foreach/>, позволяющую задать набор файлов вложенным элементом <path/> и вызвать для каждого файла указанную цель, передав ей имя файла в качестве параметра. Вот небольшой пример:
<taskdef name="foreach" classname="net.sf.antcontrib.logic.ForEach"Здесь foreach проходит по всем jar-файлам из базовой директории, и для каждого вызывает цель "mytarget", передавая ей абсолютный путь к файлу через параметр "myfile".
classpath="path/to/ant-contrib-0.6.jar"/>
<target ...>
<foreach target="mytarget" param="myfile">
<path>
<fileset dir="${basedir}">
<include name="*.jar"/>
</fileset>
</path>
</foreach>
</target>
<target name="mytarget">
<echo message="filename is ${myfile}" />
</target>
PS В принципе, в ant есть встроенная задача <apply/>, но она умеет выполнять для каждого файла из набора только внешние команды, а не внутренние цели.
четверг, 6 сентября 2012 г.
Debian Lenny: куда делись репозитории
Lenny это конечно архаизм, но всё же.
Проблема:
При попытке выполнить apt-get update стали валиться ошибки 404 и 301.
Причина:
Репозитории переехали в архив.
Решение:
Задать в /etc/apt/sources.list новые URL`ы репозиториев:
deb http://archive.debian.org/debian/ lenny main contrib non-free
deb-src http://archive.debian.org/debian/ lenny main contrib non-free
PostgreSQL: получение числа секунд, прошедших с 1970-01-01, из timestamp-поля
SELECT extract(epoch from <timestamp_column>) FROM ...Тип возвращаемого значения - double precision.
вторник, 4 сентября 2012 г.
jTrust: OnlineCrlRepository и прокси с авторизацией
Онлайн-репозиторий CRL из библиотеки jTrust реализует загрузку CRL-файлов по указанным URL`ам точек распространения сертификатов (CRL Distribution Points). Поддержка прокси в нем есть, и реализуется она передачей объекта NetworkConfig в конструктор класса:
import be.fedict.trust.NetworkConfig;
import be.fedict.trust.crl.OnlineCrlRepository;
// ...
NetworkConfig nwcfg = new NetworkConfig(proxyHost, proxyPort);
OnlineCrlRepository onlineCrlRepo = new OnlineCrlRepository(nwcfg);
Но такой вариант работает только с прокси-серверами без авторизации.
В тоже время Apache HttpClient, используемый классом OnlineCrlRepository для загрузки файла CRL, авторизацию на прокси поддерживает (не уверен, что все возможные варианты авторизации реализованы, но по крайней мере BASIC есть): http://hc.apache.org/httpclient-3.x/authentication.html#Proxy_Authentication. Но т.к. внутренние поля и методы OnlineCrlRepository являются закрытыми, наследовать его для добавления нового функционала нет особого смысла, приходится копировать исходники в свой класс, добавляя возможность установки авторизации на прокси.
Для этого я, во-первых, создал специальный класс ProxyCredentials, унаследовав be.fedict.trust.Credentials, предназначенный для хранения данных http-авторизации. Класс be.fedict.trust.Credentials содержит метод init(), который применяет авторизационные данные к объекту HttpState. Этот метод я и переопределил таким образом, чтобы он задавал не данные авторизации на конечном сайте, а данные авторизации на прокси, заменив вызов httpState.setCredentials() на httpState.setProxyCredentials():
public class ProxyCredentials extends be.fedict.trust.CredentialsТеперь достаточно в нашем варианте класса OnlineCrlRepository добавить поле для хранения объекта ProxyCredentials, setter-метод для этого поля, а также добавить в метод getCrl() применение этих авторизационных данных к объекту HttpState:
{
@Override
public void init(HttpState httpState) {
for (Credential credential : this.getCredentials()) {
AuthScope authScope = new AuthScope(credential.getHost(),
credential.getPort(), credential.getRealm(),
credential.getScheme());
UsernamePasswordCredentials usernamePasswordCredentials = new UsernamePasswordCredentials(
credential.getUsername(), credential.getPassword());
httpState.setProxyCredentials(authScope, usernamePasswordCredentials);
}
}
}
public class AdvancedOnlineCrlRepository implements CrlRepository {Теперь создание объект репозитория CRL для работы с прокси-сервером с авторизацией выглядит так:
// ..
protected ProxyCredentials proxyCredentials;
/**
* Sets the credentials for proxy authentication
* @param proxyCredentials
*/
public void setProxyCredentials(ProxyCredentials proxyCredentials) {
this.proxyCredentials = proxyCredentials;
}
// ..
protected X509CRL getCrl(URI crlUri) throws IOException,
CertificateException, CRLException, NoSuchProviderException,
NoSuchParserException, StreamParsingException {
HttpClient httpClient = new HttpClient();
if (null != this.networkConfig) {
httpClient.getHostConfiguration().setProxy(
this.networkConfig.getProxyHost(),
this.networkConfig.getProxyPort());
}
if (null != this.credentials) {
HttpState httpState = httpClient.getState();
this.credentials.init(httpState);
}
if (null != this.proxyCredentials) {
HttpState httpState = httpClient.getState();
this.proxyCredentials.init(httpState);
}
String downloadUrl = crlUri.toURL().toString();
//...
return crl;
}
}
NetworkConfig nwcfg = new NetworkConfig(proxyHost, proxyPort);
ProxyCredentials creds = new ProxyCredentials();
Credential cred = new Credential(proxyHost, proxyPort, proxyLogin, proxyPassword);
creds.addCredential(cred);
AdvancedOnlineCrlRepository onlineCrlRepo = new AdvancedOnlineCrlRepository(nwcfg);
onlineCrlRepo.setProxyCredentials(creds);
Подписаться на:
Сообщения (Atom)