/** * Este arquivo é parte do Biblivre3. * * Biblivre3 é um software livre; você pode redistribuí-lo e/ou * modificá-lo dentro dos termos da Licença Pública Geral GNU como * publicada pela Fundação do Software Livre (FSF); na versão 3 da * Licença, ou (caso queira) qualquer versão posterior. * * Este programa é distribuído na esperança de que possa ser útil, * mas SEM NENHUMA GARANTIA; nem mesmo a garantia implícita de * MERCANTIBILIDADE OU ADEQUAÇÃO PARA UM FIM PARTICULAR. Veja a * Licença Pública Geral GNU para maiores detalhes. * * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto * com este programa, Se não, veja em <http://www.gnu.org/licenses/>. * * @author Alberto Wagner <alberto@biblivre.org.br> * @author Danniel Willian <danniel@biblivre.org.br> * */ package biblivre3.cataloging.holding; import biblivre3.cataloging.bibliographic.BiblioDAO; import biblivre3.cataloging.bibliographic.RecordDTO; import biblivre3.circulation.UserDTO; import biblivre3.config.Config; import biblivre3.config.ConfigurationEnum; import biblivre3.enums.Availability; import biblivre3.enums.Database; import biblivre3.enums.HoldingSave; import biblivre3.enums.MaterialType; import biblivre3.enums.RecordStatus; import biblivre3.marcutils.MarcReader; import biblivre3.marcutils.Indexer; import biblivre3.marcutils.MarcUtils; import biblivre3.utils.ApplicationConstants; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import mercury.BaseBO; import org.apache.commons.lang.StringUtils; import org.marc4j_2_3_1.MarcXmlWriter; import org.marc4j_2_3_1.marc.DataField; import org.marc4j_2_3_1.marc.MarcFactory; import org.marc4j_2_3_1.marc.Record; import org.marc4j_2_3_1.marc.Subfield; /** * * @author Danniel Nascimento (dannielwillian@biblivre.org.br) * @since 09/03/2009 */ public class HoldingBO extends BaseBO { private HoldingDAO dao; private UserDTO userDto; public HoldingBO() { dao = new HoldingDAO(); } public HoldingBO(UserDTO userDto) { this(); this.userDto = userDto; } public final HoldingDTO getById(final int holdingId) { return dao.getById(holdingId); } public final HoldingDTO getByAsset(final String assetHolding) { return dao.getByAsset(assetHolding); } public final List<HoldingDTO> list(final RecordDTO dto) { return dao.list(dto); } public final boolean delete(final HoldingDTO hdto) { return dao.delete(hdto); } private Integer getNextSerial() { return dao.getNextSerial(); } public final String getNextAvailableAsset() { String prefix = Config.getConfigProperty(ConfigurationEnum.ASSET_PREFIX.name()) + "." + Calendar.getInstance().get(Calendar.YEAR) + "."; int nextAsset = dao.getNextAutomaticAsset(prefix); return prefix + nextAsset; } public final String getNextLocationD(final int recordSerial) { int nextAsset = dao.getNextLocationD(recordSerial); return "ex." + nextAsset; } public final boolean checkAssetAvailability(final String asset, int holdingSerial) { return dao.isAssetAvailable(asset, holdingSerial); } public final boolean checkAssetAvailability(final String asset) { return this.checkAssetAvailability(asset, 0); } public final HoldingSave insert(final int recordSerial, final Database base, final String marc, final Availability availability) { final Record holding = MarcReader.marcToRecord(marc, MaterialType.HOLDINGS, RecordStatus.NEW); String assetHolding = Indexer.listAssetHolding(holding); boolean emptyAssetHolding = StringUtils.isBlank(assetHolding); if (emptyAssetHolding) { assetHolding = this.getNextAvailableAsset(); MarcUtils.setAssetHolding(holding, assetHolding); } else if (!this.checkAssetAvailability(assetHolding)) { return HoldingSave.ASSET_HOLDING_ALREADY_IN_USE; } if (this.insert(holding, recordSerial, base, availability)) { return emptyAssetHolding ? HoldingSave.SUCCESS_WITH_NEW_ASSET_HOLDING : HoldingSave.SUCCESS; } else { return HoldingSave.ERROR; } } private boolean insert(final Record holding, final int recordSerial, final Database base, final Availability availability) { final Integer holdingSerial = this.getNextSerial(); final Date now = new Date(); MarcUtils.setCF001(holding, holdingSerial); MarcUtils.setCF004(holding, recordSerial); MarcUtils.setCF005(holding, now); final String iso2709 = MarcUtils.recordToIso2709(holding); final HoldingDTO dto = new HoldingDTO(); dto.setSerial(holdingSerial); dto.setRecordSerial(recordSerial); dto.setCreated(now); dto.setModified(now); dto.setIso2709(iso2709); dto.setDatabase(base); dto.setAssetHolding(Indexer.listAssetHolding(holding)); dto.setLocationD(Indexer.listLocation(holding)[3]); dto.setAvailability(availability); boolean success = dao.insert(dto); if (success && this.userDto != null) { return dao.updateHoldingCreationCounter(this.userDto); } return success; } public final HoldingSave update(final int holdingSerial, final int recordSerial, final String marc, final Availability availability) { final Record holding = MarcReader.marcToRecord(marc, MaterialType.HOLDINGS, RecordStatus.CORRECTED); String assetHolding = Indexer.listAssetHolding(holding); boolean emptyAssetHolding = StringUtils.isBlank(assetHolding); if (emptyAssetHolding) { assetHolding = this.getNextAvailableAsset(); MarcUtils.setAssetHolding(holding, assetHolding); } else if (!this.checkAssetAvailability(assetHolding, holdingSerial)) { return HoldingSave.ASSET_HOLDING_ALREADY_IN_USE; } if (this.update(holding, holdingSerial, recordSerial, availability)) { return emptyAssetHolding ? HoldingSave.SUCCESS_WITH_NEW_ASSET_HOLDING : HoldingSave.SUCCESS; } else { return HoldingSave.ERROR; } } private boolean update(final Record holding, final int holdingSerial, final int recordSerial, final Availability availability) { final Date now = new Date(); MarcUtils.setCF001(holding, holdingSerial); MarcUtils.setCF004(holding, recordSerial); MarcUtils.setCF005(holding, now); final String iso2709 = MarcUtils.recordToIso2709(holding); final HoldingDTO dto = new HoldingDTO(); dto.setSerial(holdingSerial); dto.setIso2709(iso2709); dto.setModified(now); dto.setAssetHolding(Indexer.listAssetHolding(holding)); dto.setLocationD(Indexer.listLocation(holding)[3]); dto.setAvailability(availability); return dao.update(dto); } public final Integer countAvailableHoldings(final int recordSerial) { return dao.countAvailableHoldings(recordSerial); } public final Integer countAvailableHoldings(final RecordDTO dto) { return this.countAvailableHoldings(dto.getRecordSerial()); } public final Integer countHoldings(final int recordSerial) { return dao.countHoldings(recordSerial); } public final Integer countHoldings(final RecordDTO dto) { return this.countHoldings(dto.getRecordSerial()); } public boolean generateLabel(final int holdingSerial, final int recordSerial, final RecordDTO record, final HoldingDTO holding) { String[] biblioDetails = this.getBibliographicDetails(record); String[] locDetails = this.getLocationDetails(holding); return this.generateLabel(holdingSerial, recordSerial, biblioDetails, locDetails, holding.getAssetHolding()); } public boolean generateLabel(final int holdingSerial, final int recordSerial, String[] biblioDetails, String[] locDetails, String assetHolding) { final LabelDTO ldto = new LabelDTO(); ldto.setHoldingSerial(holdingSerial); ldto.setRecordSerial(recordSerial); ldto.setAssetHolding(assetHolding); ldto.setAuthor(biblioDetails[0]); ldto.setTitle(biblioDetails[1]); ldto.setLocationA(locDetails[0]); ldto.setLocationB(locDetails[1]); ldto.setLocationC(locDetails[2]); ldto.setLocationD(locDetails[3]); return dao.insertLabel(ldto); } public String[] getBibliographicDetails(final RecordDTO recordDto) { Record record = MarcUtils.iso2709ToRecord(recordDto.getIso2709()); String[] biblioDetails = new String[3]; biblioDetails[0] = Indexer.listFirstAuthors(record); biblioDetails[1] = Indexer.listOneTitle(record); return biblioDetails; } public String[] getLocationDetails(final HoldingDTO holdingDTO) { Record record = MarcUtils.iso2709ToRecord(holdingDTO.getIso2709()); return Indexer.listLocation(record); } public boolean createAutomaticHolding(final Record record, final Database base, final int recordSerial, final Availability availability, String[] ex_auto) { try { int holdingCount = StringUtils.isNumeric(ex_auto[0]) && StringUtils.isNotBlank(ex_auto[0]) ? Integer.parseInt(ex_auto[0]) : 1; int volumeNumber = StringUtils.isNumeric(ex_auto[1]) && StringUtils.isNotBlank(ex_auto[1]) ? Integer.parseInt(ex_auto[1]) : 0; int volumeCount = StringUtils.isNumeric(ex_auto[2]) && StringUtils.isNotBlank(ex_auto[2]) ? Integer.parseInt(ex_auto[2]) : 1; String deposit = ex_auto[3]; String acquisitionType = ex_auto[4]; String dt_tomb = ex_auto[5]; String[] notes = new String[3]; notes[0] = 'a' + deposit; notes[1] = 'c' + acquisitionType; notes[2] = 'd' + dt_tomb; boolean success = true; String[] location = Indexer.listLocation(record); for (int j = 0; j < volumeCount; j++) { for (int i = 0; i < holdingCount; i++) { String[] vetHolding = new String[4]; vetHolding[0] = "a" + location[0]; vetHolding[1] = "b" + location[1]; vetHolding[2] = "c"; if (StringUtils.isNotBlank(location[2])) { vetHolding[2] += location[2]; } else { if (volumeNumber != 0) { vetHolding[2] += "v." + volumeNumber; } else if (volumeCount > 1) { vetHolding[2] += "v." + (j + 1); } } vetHolding[3] = 'd' + "ex." + (i + 1); Record holding = this.getRecordHolding(vetHolding, notes); MarcUtils.setAssetHolding(holding, this.getNextAvailableAsset()); success &= this.insert(holding, recordSerial, base, availability); } } return success; } catch (RuntimeException rex) { throw rex; } } public Record getRecordHolding(String[] subfields, String[] notes) { MarcFactory factory = MarcFactory.newInstance(); Record record = factory.newRecord(); DataField df = factory.newDataField("090", '_', '_'); record.addVariableField(df); for (int i = 0; i < 4; i++) { if (StringUtils.isNotBlank(subfields[i])) { final char code = subfields[i].charAt(0); Subfield subfield = factory.newSubfield(code, subfields[i].substring(1)); df.addSubfield(subfield); } } DataField df1 = factory.newDataField("541", '_', '_'); record.addVariableField(df1); for (int i = 0; i < 3; i++) { if (StringUtils.isNotBlank(notes[i])) { final char code = notes[i].charAt(0); Subfield subfield = factory.newSubfield(code, notes[i].substring(1)); df1.addSubfield(subfield); } } record.setLeader(MarcUtils.createBasicLeader(MaterialType.HOLDINGS, RecordStatus.NEW)); return record; } public File exportRecords(String format, Database database) { if (StringUtils.isBlank(format)) { return null; } else if (format.equals("iso2709")) { return createIsoFile(database); } else if (format.equals("xml")) { return createXmlFile(database); } else { return null; } } private File createIsoFile(Database database) { try { File file = File.createTempFile("bib3_", null); FileOutputStream fos = new FileOutputStream(file); OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8"); HoldingDAO holdingDao = new HoldingDAO(); int limit = 100; int recordCount = holdingDao.countAll(database); for (int offset = 0; offset < recordCount; offset += limit) { List<HoldingDTO> records = holdingDao.list(database, offset, limit); for (HoldingDTO dto : records) { writer.write(dto.getIso2709()); writer.write(ApplicationConstants.LINE_BREAK); } } writer.flush(); writer.close(); return file; } catch (Exception e) { log.error(e.getMessage(), e); } return null; } private File createXmlFile(Database database) { try { File file = File.createTempFile("bib3_", null); FileOutputStream fos = new FileOutputStream(file); MarcXmlWriter writer = new MarcXmlWriter(fos, true); HoldingDAO holdingDao = new HoldingDAO(); int limit = 100; int recordCount = holdingDao.countAll(null); for (int offset = 0; offset < recordCount; offset += limit) { List<HoldingDTO> records = holdingDao.list(database, offset, limit); for (HoldingDTO dto : records) { final Record record = MarcUtils.iso2709ToRecord(dto.getIso2709()); if (record != null) { writer.write(record); } } } writer.close(); return file; } catch (Exception e) { log.error(e.getMessage(), e); } return null; } }