/* * Copyright (C) 2011 Jan Pokorsky * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package cz.cas.lib.proarc.webapp.client.ds; import com.google.gwt.core.client.Callback; import com.google.gwt.event.shared.HandlerRegistration; import com.smartgwt.client.data.DataSource; import com.smartgwt.client.data.DataSourceField; import com.smartgwt.client.data.Record; import com.smartgwt.client.data.RecordList; import com.smartgwt.client.data.RestDataSource; import com.smartgwt.client.data.ResultSet; import com.smartgwt.client.data.events.DataArrivedEvent; import com.smartgwt.client.data.events.DataArrivedHandler; import com.smartgwt.client.data.fields.DataSourceBooleanField; import com.smartgwt.client.data.fields.DataSourceTextField; import com.smartgwt.client.types.DSDataFormat; import com.smartgwt.client.types.FetchMode; import com.smartgwt.client.types.FieldType; import com.smartgwt.client.widgets.menu.Menu; import com.smartgwt.client.widgets.menu.MenuItem; import cz.cas.lib.proarc.webapp.client.ClientUtils; import cz.cas.lib.proarc.webapp.shared.rest.DigitalObjectResourceApi; import java.util.logging.Logger; /** * Lists Fedora models. * * @author Jan Pokorsky */ public class MetaModelDataSource extends RestDataSource { private static final Logger LOG = Logger.getLogger(MetaModelDataSource.class.getName()); public static final String ID = "MetaModelDataSource"; public static final String FIELD_PID = DigitalObjectResourceApi.METAMODEL_PID_PARAM; public static final String FIELD_DISPLAY_NAME = DigitalObjectResourceApi.METAMODEL_DISPLAYNAME_PARAM; public static final String FIELD_IS_ROOT = DigitalObjectResourceApi.METAMODEL_ROOT_PARAM; public static final String FIELD_IS_LEAF = DigitalObjectResourceApi.METAMODEL_LEAF_PARAM; public static final String FIELD_METADATA_FORMAT = DigitalObjectResourceApi.METAMODEL_METADATAFORMAT_PARAM; public static final String FIELD_EDITOR = DigitalObjectResourceApi.METAMODEL_MODSCUSTOMEDITORID_PARAM; public static final String FIELD_DATASTREAM_EDITORS = DigitalObjectResourceApi.METAMODEL_DATASTREAMEDITOR_PARAM; /** * Synthetic field holding {@link MetaModelRecord} instance. */ public static final String FIELD_MODELOBJECT = "MetaModelRecord"; private static ResultSet resultSet; public MetaModelDataSource() { setID(ID); setDataFormat(DSDataFormat.JSON); setDataURL(RestConfig.URL_DIGOBJECT_METAMODEL); DataSourceTextField pid = new DataSourceTextField(FIELD_PID); pid.setPrimaryKey(true); DataSourceTextField displayName = new DataSourceTextField(FIELD_DISPLAY_NAME); DataSourceBooleanField isRoot = new DataSourceBooleanField(FIELD_IS_ROOT); DataSourceBooleanField isLeaf = new DataSourceBooleanField(FIELD_IS_LEAF); DataSourceTextField editor = new DataSourceTextField(FIELD_EDITOR); DataSourceTextField metadataFormat = new DataSourceTextField(FIELD_METADATA_FORMAT); DataSourceField dataStreamEditors = new DataSourceField(FIELD_DATASTREAM_EDITORS, FieldType.ANY); dataStreamEditors.setCanEdit(Boolean.FALSE); dataStreamEditors.setHidden(Boolean.TRUE); setFields(pid, displayName, isRoot, isLeaf, metadataFormat, editor, dataStreamEditors); setRequestProperties(RestConfig.createRestRequest(getDataFormat())); } public static MetaModelDataSource getInstance() { MetaModelDataSource ds = (MetaModelDataSource) DataSource.get(ID); ds = ds != null ? ds : new MetaModelDataSource(); return ds; } public static ResultSet getModels() { return getModels(false); } public static ResultSet getModels(boolean reload) { if (resultSet == null) { resultSet = new ResultSet(getInstance()); resultSet.setFetchMode(FetchMode.LOCAL); resultSet.get(0); } else if (reload) { resultSet.invalidateCache(); resultSet.get(0); } return resultSet; } public static void getModels(boolean reload, final Callback<ResultSet, Void> callback) { final ResultSet models = getModels(reload); if (models.lengthIsKnown()) { callback.onSuccess(models); } else { final HandlerRegistration[] handler = new HandlerRegistration[1]; handler[0] = models.addDataArrivedHandler(new DataArrivedHandler() { @Override public void onDataArrived(DataArrivedEvent event) { handler[0].removeHandler(); callback.onSuccess(models); } }); } } /** * Gets model of a digital object. It searches for synthetic attribute * {@link #FIELD_MODELOBJECT}. If not found it searches for {@link SearchDataSource#FIELD_MODEL} * and sets FIELD_MODELOBJECT attribute. * * @param digitalObject record fetched by {@link SearchDataSource} or {@link RelationDataSource} * @return model object or {@code null} */ public static MetaModelRecord getModel(Record digitalObject) { MetaModelRecord mmr = (MetaModelRecord) digitalObject.getAttributeAsObject(FIELD_MODELOBJECT); if (mmr == null) { String model = digitalObject.getAttribute(SearchDataSource.FIELD_MODEL); if (model != null) { if (resultSet == null) { return null; } Record mr = resultSet.findByKey(model); if (mr != null) { mmr = MetaModelRecord.get(mr); digitalObject.setAttribute(FIELD_MODELOBJECT, mmr); } else { ClientUtils.severe(LOG, "unkown model ID '%s' of record %s", model, digitalObject.getAttribute(SearchDataSource.FIELD_PID)); } } } return mmr; } public static Menu createMenu(RecordList modelRecords, boolean includeRoots) { return createMenu(modelRecords.toArray(), includeRoots); } /** * Helper to create menu listing object models. * <p>{@link Menu#setDataSource} is broken (SmartGWT 3.0, 4.0). * @param modelRecords fetched model records * @param includeRoots include root models in menu? * @return the menu */ public static Menu createMenu(Record[] modelRecords, boolean includeRoots) { Menu menu = new Menu(); for (int i = 0; i < modelRecords.length; i++) { MetaModelRecord mmr = MetaModelRecord.get(modelRecords[i]); if (includeRoots || !mmr.isRoot()) { MenuItem menuItem = new MenuItem(mmr.getDisplayName()); menuItem.setAttribute(FIELD_PID, mmr.getId()); menu.addItem(menuItem); } } return menu; } public static final class MetaModelRecord { private final Record record; public static MetaModelRecord get(Record r) { return r == null ? null : new MetaModelRecord(r); } public MetaModelRecord(Record r) { this.record = r; } public String getId() { return record.getAttribute(FIELD_PID); } public boolean isRoot() { return record.getAttributeAsBoolean(FIELD_IS_ROOT); } public String getMetadataFormat() { return record.getAttribute(FIELD_METADATA_FORMAT); } public String getEditorId() { return record.getAttribute(FIELD_EDITOR); } public String getDisplayName() { return record.getAttribute(FIELD_DISPLAY_NAME); } public boolean isSupportedDatastream(String dsEditor) { String[] supportedEditors = record.getAttributeAsStringArray(FIELD_DATASTREAM_EDITORS); for (String supportedEditor : supportedEditors) { if (dsEditor.equals(supportedEditor)) { return true; } } return false; } } }