JAVA библиотека padeg — новогодний подарок хабру

в 5:29, , рубрики: Delphi, java

Да-да, это та самая библиотека padeg.dll, но работающая везде где есть java. Авторы Sergey V. Plahov aka Seer and Gennady Pokatashkin ©
Собственно, история простая. Началась она в 2007 году, когда мне срочно понадобилось склонять ФИО и должности для одного корпоративного проекта. В принципе, данный функционал не стоял в требованиях заказчика, но нужны были «плюшки», и автоматические склонения — это как раз одна из плюшек.
Довольно быстро удалось связаться с одним из авторов библиотеки, и после перечисления небольшой суммы были получены исходники на Delphi, которые затем портировались в JAVA. По первоначальной задумке java и delphi исходники должны были максимально совпадать, чтобы впоследствии можно было вносить параллельные правки. Делалось так: брались исходники на delphi, менялись расширения pas→java, и добавлялись в проект. Дальше шла правка синтаксиса. Но фактически delphi — код пришлось сильно рефакторизовать, поскольку он состоял в основном из многоэтажных if-ов и внутренних процедур, содержал глобальные переменные и не был приспособлен для многопоточной работы.
Как бы там ни было, библиотека портирована. На вопрос о копирайте мне было разрешено делать с результатом что угодно, но поскольку delphi-библиотека распространялась на условиях shareware, я не стал публиковать java-порт.
С тех пор прошло 5 лет, и я думаю, хватит одному пользоваться инструментом, которой найдется применение в хозяйстве отечественного java — разработчика. К тому же праздник на носу. Поэтому загружайте

техническая информация

Библиотека совместима с java 1.5, но, в принципе, ничто не мешает сделать порт и в предыдущие версии java. Необходимо будет только убрать типизацию коллекций, и с многопоточностью чуть больше повозиться (для работы со словарем исключений были использованы volatile переменные);
API сделан максимально похожим на API padeg.dll;
Кодировка ресурсов, содержащихся в библиотеке — windows-1251 (для совместимости с оригинальной библиотекой). Если необходимо будет подключить внешний файл исключений, то он также должен быть в кодировке windows-1251. Существует также возможность загрузки исключений с помощью итератора, например, из таблицы БД (

Iterator<String>

).
Тестовое приложение можно посмотреть на OpenShift; Там же и сама библиотека (хабрахранилище принимает только рисунки, поэтому придется загружать библиотеку прямо из ресурсов тестового приложения).

Исходный код тестового приложения

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.model.SelectItem;

import padeg.lib.Padeg;

@ManagedBean
public class PadegBean implements Serializable {

	private static final long serialVersionUID = 1L;
	
	public class ResultItem implements Serializable {
		private static final long serialVersionUID = 1L;
		private int padeg;
		private String fio;
		private String appointment;
		private String office;
		public int getPadeg() {
			return padeg;
		}
		public String getFio() {
			return fio;
		}
		public String getAppointment() {
			return appointment;
		}
		public String getOffice() {
			return office;
		}
	}

	public PadegBean() {
	}

	private String lastName = "Балаганов";
	private String firstName = "Шура";
	private String middleName;
	private String appointment = "уполномоченный по копытам";
	private String office = "Черноморское отделение Арбатовской конторы по заготовке рогов и копыт";
	private List<String> fioResult;
	private List<String> appointmentResult;
	private List<String> officeResult;
	private String sexStr = "true";
	private static final SelectItem[] sexItems = {
		new SelectItem("true","мужской"),
		new SelectItem("false","женский"),
		new SelectItem("auto","автоопределение по отчеству")
	};
	private List<ResultItem> resultItems;
	
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getMiddleName() {
		return middleName;
	}
	public void setMiddleName(String middleName) {
		this.middleName = middleName;
	}
	public String getAppointment() {
		return appointment;
	}
	public void setAppointment(String appointment) {
		this.appointment = appointment;
	}
	public String getOffice() {
		return office;
	}
	public void setOffice(String office) {
		this.office = office;
	}
	public String getSexStr() {
		return sexStr;
	}
	public void setSexStr(String sexStr) {
		this.sexStr = sexStr;
	}
	public SelectItem[] getSexItems() {
		return sexItems;
	}

	public List<String> getFioResult() {
		if (fioResult==null) {
			declFio();
		}
		return fioResult;
	}
	public List<String> getAppointmentResult() {
		return appointmentResult;
	}
	public List<String> getOfficeResult() {
		return officeResult;
	}
	public List<ResultItem> getResultItems() {
		if (resultItems == null) {
			declAll();
		}
		return resultItems;
	}

	public void declAll() {
		resultItems = new ArrayList<PadegBean.ResultItem>();
		for (int i=1;i<=6;i++) {
			ResultItem item = new ResultItem();
			item.padeg = i;
			resultItems.add(item);
			
			try {
				if ("auto".equals(sexStr)) {
					item.fio = Padeg.getFIOPadegAS(lastName, firstName, middleName, i);
				} else {
					boolean sex = Boolean.parseBoolean(sexStr);
					item.fio = Padeg.getFIOPadeg(lastName, firstName, middleName, sex, i);
				}
			} catch (Exception e) {
				item.fio = e.getMessage();
			}
			
			try {
				//item.appointment = Padeg.getFullAppointmentPadeg(appointment, office, i);
				item.appointment = Padeg.getAppointmentPadeg(appointment, i);
			} catch (Exception e) {
				item.appointment = e.getMessage();
			}
			
			try {
				item.office = Padeg.getOfficePadeg(office, i);
			} catch (Exception e) {
				item.office = e.getMessage();
			}
		}
	}
	
	public void declFio(){
		fioResult = new ArrayList<String>();
		if ("auto".equals(sexStr)) {
			for (int i=1;i<=6;i++) {
				try {
					fioResult.add(Padeg.getFIOPadegAS(lastName, firstName, middleName, i));
				} catch (Exception e) {
					fioResult.add(e.getMessage());
				}
			}
		} else {
			boolean sex = Boolean.parseBoolean(sexStr);
			for (int i=1;i<=6;i++) {
				try {
					fioResult.add(Padeg.getFIOPadeg(lastName, firstName, middleName, sex, i));
				} catch (Exception e) {
					fioResult.add(e.getMessage());
				}
			}
		}
	}

	public void declAppointment(){
		appointmentResult = new ArrayList<String>();
		for (int i=1;i<=6;i++) {
			appointmentResult.add(Padeg.getFullAppointmentPadeg(appointment, office, i));
		}
	}

	public void declOfice(){
		officeResult = new ArrayList<String>();
		for (int i=1;i<=6;i++) {
			officeResult.add(Padeg.getOfficePadeg(office, i));
		}
	}
}

Автор: ivanra

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js