/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.esri.gpt.catalog.harvest.repository; import com.esri.gpt.catalog.harvest.protocols.HarvestProtocolAgp2Agp; import com.esri.gpt.catalog.publication.PublicationRequest; import com.esri.gpt.catalog.schema.Schema; import com.esri.gpt.control.view.SelectablePublishers; import com.esri.gpt.control.webharvest.IterationContext; import com.esri.gpt.control.webharvest.protocol.ProtocolInvoker; import com.esri.gpt.framework.collection.StringAttributeMap; import com.esri.gpt.framework.context.RequestContext; import com.esri.gpt.framework.resource.api.Native; import com.esri.gpt.framework.resource.query.QueryBuilder; import com.esri.gpt.framework.security.identity.NotAuthorizedException; import com.esri.gpt.framework.security.principal.Publisher; import com.esri.gpt.framework.security.principal.RoleSet; import com.esri.gpt.framework.util.UuidUtil; import java.util.ArrayList; import java.util.Date; /** * Complete update request. */ public class HrCompleteUpdateRequest extends HrRequest { private HrRecord record; /** * Creates instance of the request. * @param context request context * @param record record */ public HrCompleteUpdateRequest(RequestContext context, HrRecord record) { super(context, new HrCriteria(), new HrResult()); this.record = record; } /** * Creates native resource based on the information from the repository. * @param repository repository * @return native resource or <code>null</code> if no native resource * @throws Exception if accessing resource fails */ private Native createNativeResource(HrRecord repository) throws Exception { // declare placeholder for any exception thrown by query builder final ArrayList<Exception> exceptions = new ArrayList<Exception>(); // create such an instance of the iteration context so it will store each // exception in the placeholder IterationContext iterationContext = new IterationContext() { public void onIterationException(Exception ex) { exceptions.add(ex); } }; // create new query builder specific for the repository QueryBuilder queryBuilder = repository.newQueryBuilder(iterationContext); // get native resource; this may throw exception(s) stored later in the // placeholder Native nativeResource = queryBuilder.getNativeResource(); // assure there are no exceptions; if there are any, throw the first one if (exceptions.size() > 0) { throw exceptions.get(0); } return nativeResource; } /** * Executes request. * @throws Exception if any error occurred */ public boolean execute() throws Exception { RequestContext context = getRequestContext(); SelectablePublishers selectablePublishers = new SelectablePublishers(); selectablePublishers.build(context, isAdministrator(context)); Publisher user = selectablePublishers.selectedAsPublisher(context, isAdministrator(context)); RoleSet roleSet = new RoleSet(); roleSet.add("gptAdministrator"); roleSet.add("gptPublisher"); user.getAuthenticationStatus().authorizeAction(roleSet); boolean hostUrlChanged = true; boolean titleChanged = true; boolean findableChanged = true; boolean creating = !UuidUtil.isUuid(record.getUuid()); if (!creating) { HrSelectRequest select = new HrSelectRequest(context, record.getUuid()); select.execute(); HrRecords records = select.getQueryResult().getRecords(); if (records.size() > 0) { HrRecord oldRecord = records.get(0); if (user.getLocalID()!=oldRecord.getOwnerId()) { if (!user.getIsAdministrator()) { throw new NotAuthorizedException("Not authorized."); } } if (record.getHostUrl().equals(oldRecord.getHostUrl())) { hostUrlChanged = false; } if (record.getName().equals(oldRecord.getName())) { titleChanged = false; } if (record.getFindable()==oldRecord.getFindable()) { findableChanged = false; } } } if (hostUrlChanged) { // if creaing new repository, make sure that no record with identical // host URL exist in the database HrAssertUrlRequest assertUrlRequest = new HrAssertUrlRequest(context, record.getHostUrl()); assertUrlRequest.executeAssert(); } // create native resource Native nativeResource = null; // check if either host URL or title has changed if (hostUrlChanged || titleChanged || (findableChanged && record.getFindable())) { record.setUpdateDate(new Date()); // if hot URL or title has changed than proceed with generation of the // native resource String title = ""; // First, try to create native resource from the response nativeResource = createNativeResource(record); if (nativeResource == null) { // if no native resource available, create an artificial one based on //the information (host URL & title) from the repository. nativeResource = record.generateNativeResource(); // get title title = record.getName(); ProtocolInvoker.setLockTitle(record.getProtocol(), false); } else { // if the native resource is available, make sure it's a valid metadata resource // prepare record for publication; it will validate schema PublicationRequest pubReq = new PublicationRequest(context, user, nativeResource.getContent()); Schema schema = pubReq.prepareForPublication(); boolean lockTitle = false; if (record.getName().length() == 0) { title = schema.getMeaning().getTitle(); } else { if (!ProtocolInvoker.getLockTitle(record.getProtocol())) { lockTitle = titleChanged; } else { lockTitle = true; } title = record.getName(); } ProtocolInvoker.setLockTitle(record.getProtocol(), lockTitle); } if (title.length() == 0) { // if no title, create one using host URL if (!(record.getProtocol() instanceof HarvestProtocolAgp2Agp)) { title = record.getHostUrl(); } else { HarvestProtocolAgp2Agp p = (HarvestProtocolAgp2Agp)record.getProtocol(); title = p.getSourceHost() + " -> " + p.getDestinationHost(); } ProtocolInvoker.setLockTitle(record.getProtocol(), false); } record.setName(title); } HrUpdateRequest request = new HrUpdateRequest(context, user, record); request.executeUpdate(nativeResource); return creating; } /** * Checks if user is administrator. * @param context request context * @return <code>true</code> if user is administrator */ private boolean isAdministrator(RequestContext context) { return context.getUser() != null && context.getUser().getAuthenticationStatus().getWasAuthenticated() && context.getUser().getAuthenticationStatus(). getAuthenticatedRoles().hasRole("gptAdministrator"); } }