Project

General

Profile

« Previous | Next » 

Revision 6803

new jars with many changes -- including new CN methods: ping, describe, listChecksumAlgorithm. Removed MN.setAccessPolicy. Refactored CN.setOwner() to CN.setRightsHolder().

View differences:

src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java
22 22
 */
23 23
package edu.ucsb.nceas.metacat.restservice;
24 24

  
25
import java.io.ByteArrayInputStream;
26 25
import java.io.File;
27 26
import java.io.FileInputStream;
28 27
import java.io.IOException;
......
61 60
import org.dataone.service.exceptions.ServiceFailure;
62 61
import org.dataone.service.exceptions.SynchronizationFailed;
63 62
import org.dataone.service.exceptions.UnsupportedType;
64
import org.dataone.service.types.v1.AccessPolicy;
65 63
import org.dataone.service.types.v1.Checksum;
66 64
import org.dataone.service.types.v1.DescribeResponse;
67 65
import org.dataone.service.types.v1.Event;
......
76 74
import org.dataone.service.types.v1.Permission;
77 75
import org.dataone.service.types.v1.Subject;
78 76
import org.dataone.service.types.v1.SystemMetadata;
77
import org.dataone.service.util.Constants;
79 78
import org.dataone.service.util.DateTimeMarshaller;
80 79
import org.dataone.service.util.ExceptionHandler;
81 80
import org.dataone.service.util.TypeMarshaller;
82 81
import org.jibx.runtime.JiBXException;
83 82
import org.xml.sax.SAXException;
84 83

  
85
import edu.ucsb.nceas.metacat.dataone.CNodeService;
86 84
import edu.ucsb.nceas.metacat.dataone.MNodeService;
87 85

  
88 86
/**
......
175 173
                    // node response
176 174
                    node();
177 175
                    status = true;
178
                } else if (resource.startsWith(RESOURCE_ACCESS_RULES)) {
179
                    if (httpVerb == PUT) {
180
                    	// after the command
181
                        extra = parseTrailing(resource, RESOURCE_ACCESS_RULES);
182
	                	// set the access rules
183
	                    setAccess(extra);
184
	                    status = true;
185
	                    logMetacat.debug("done setting access");
186
                    }
187 176
                } else if (resource.startsWith(RESOURCE_IS_AUTHORIZED)) {
188 177
                    if (httpVerb == GET) {
189 178
                    	// after the command
......
248 237
                    if (httpVerb == GET) {
249 238
                    	// after the command
250 239
                        extra = parseTrailing(resource, RESOURCE_MONITOR);
251
                    	// health monitoring calls
252
                        status = monitor(extra);
240
                        
241
                        // ping
242
                        if (extra.toLowerCase().equals("ping")) {
243
                            logMetacat.debug("processing ping request");
244
                            Date result = MNodeService.getInstance(request).ping();
245
                            // TODO: send to output	
246
                            status = true;
247
                            
248
                        } else {
249
	                    	// health monitoring calls
250
	                        status = monitor(extra);
251
                        }
252
                        
253 253
                    }
254 254
                } else if (resource.startsWith(RESOURCE_REPLICATE)) {
255 255
                	if (httpVerb == POST) {
......
452 452
        logMetacat.debug("verb is GET");
453 453
        logMetacat.debug("pathInfo is " + pathInfo);
454 454
        
455
        if (pathInfo.toLowerCase().equals("ping")) {
456
            logMetacat.debug("processing ping request");
457
            boolean result = MNodeService.getInstance(request).ping();
458
            return result;
459
            
460
        } else if (pathInfo.toLowerCase().equals("status")) {
455
        if (pathInfo.toLowerCase().equals("status")) {
461 456
            logMetacat.debug("processing status request");
462 457
            // TODO: implement in MNCore
463 458
            //MNodeService.getInstance().getStatus();
......
1075 1070
        TypeMarshaller.marshalTypeToOutputStream(id, out);
1076 1071
        
1077 1072
    }    
1078
    
1079
    /**
1080
     * set the access perms on a document
1081
     * @throws JiBXException 
1082
     * @throws InvalidRequest 
1083
     * @throws NotImplemented 
1084
     * @throws NotAuthorized 
1085
     * @throws NotFound 
1086
     * @throws ServiceFailure 
1087
     * @throws InvalidToken 
1088
     * @throws IllegalAccessException 
1089
     * @throws InstantiationException 
1090
     * @throws IOException 
1091
     * @throws SAXException 
1092
     * @throws ParserConfigurationException 
1093
     */
1094
    protected void setAccess(String pid) throws JiBXException, InvalidToken, ServiceFailure, NotFound, NotAuthorized, NotImplemented, InvalidRequest, IOException, InstantiationException, IllegalAccessException, ParserConfigurationException, SAXException
1095
    {
1096
    
1097
        //String pid = params.get("pid")[0];
1098
        Identifier id = new Identifier();
1099
        id.setValue(pid);
1100
        
1101
        AccessPolicy accessPolicy = collectAccessPolicy();
1102
        MNodeService.getInstance(request).setAccessPolicy(session, id, accessPolicy);
1103
        
1104
        
1105
    }
1106 1073

  
1107 1074
	protected SynchronizationFailed collectSynchronizationFailed() throws IOException, ServiceFailure, InvalidRequest, JiBXException, InstantiationException, IllegalAccessException, ParserConfigurationException, SAXException  {
1108 1075
		
src/edu/ucsb/nceas/metacat/restservice/CNResourceHandler.java
56 56
import org.dataone.service.exceptions.UnsupportedType;
57 57
import org.dataone.service.types.v1.AccessPolicy;
58 58
import org.dataone.service.types.v1.Checksum;
59
import org.dataone.service.types.v1.ChecksumAlgorithmList;
60
import org.dataone.service.types.v1.DescribeResponse;
59 61
import org.dataone.service.types.v1.Event;
60 62
import org.dataone.service.types.v1.Identifier;
61 63
import org.dataone.service.types.v1.Log;
......
71 73
import org.dataone.service.types.v1.ReplicationStatus;
72 74
import org.dataone.service.types.v1.Subject;
73 75
import org.dataone.service.types.v1.SystemMetadata;
76
import org.dataone.service.util.Constants;
74 77
import org.dataone.service.util.DateTimeMarshaller;
75 78
import org.dataone.service.util.TypeMarshaller;
76 79
import org.jibx.runtime.JiBXException;
77 80
import org.xml.sax.SAXException;
78 81

  
79 82
import edu.ucsb.nceas.metacat.dataone.CNodeService;
83
import edu.ucsb.nceas.metacat.dataone.MNodeService;
80 84
import edu.ucsb.nceas.metacat.properties.PropertyService;
81 85
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
82 86

  
......
247 251
                    } else if (httpVerb == POST) {
248 252
                        putObject(extra, FUNCTION_NAME_INSERT);
249 253
                        status = true;
254
                    } else if (httpVerb == HEAD) {
255
                        describeObject(extra);
256
                        status = true;
250 257
                    }
251 258

  
252 259
                } else if (resource.startsWith(RESOURCE_FORMATS)) {
......
330 337
                    isNodeAuthorized(extra);
331 338
                    status = true;
332 339

  
340
                } else if (resource.startsWith(Constants.RESOURCE_MONITOR_PING)) {
341
                    if (httpVerb == GET) {
342
                    	// after the command
343
                        extra = parseTrailing(resource, Constants.RESOURCE_MONITOR_PING);
344
                        
345
                        logMetacat.debug("processing ping request");
346
                        Date result = CNodeService.getInstance(request).ping();
347
                        // TODO: send to output	
348
                        status = true;
349
                    }
350
                } else if (resource.startsWith(Constants.RESOURCE_CHECKSUM)) {
351
                    if (httpVerb == GET) {
352
                        listChecksumAlgorithms();
353
                        status = true;
354
                    }
333 355
                }
334 356

  
335 357
                if (!status) {
......
653 675
                stylesheet);
654 676

  
655 677
    }
678
    
679
    private void listChecksumAlgorithms() throws IOException, ServiceFailure,
680
			NotImplemented, JiBXException {
681
		logMetacat.debug("Entering listFormats()");
656 682

  
683
		ChecksumAlgorithmList result = CNodeService.getInstance(request).listChecksumAlgorithms();
684

  
685
		// get the response output stream
686
		OutputStream out = response.getOutputStream();
687
		response.setStatus(200);
688
		response.setContentType("text/xml");
689

  
690
		// style the object with a processing directive
691
		String stylesheet = null;
692
		try {
693
			stylesheet = PropertyService.getProperty("dataone.types.xsl");
694
		} catch (PropertyNotFoundException e) {
695
			logMetacat.warn("Could not locate DataONE types XSLT: "
696
					+ e.getMessage());
697
		}
698

  
699
		TypeMarshaller.marshalTypeToOutputStream(result, out, stylesheet);
700

  
701
	}
702
    
657 703
    /**
704
     * http://mule1.dataone.org/ArchitectureDocs-current/apis/CN_APIs.html#CNRead.describe
705
     * @param pid
706
     * @throws InvalidToken
707
     * @throws ServiceFailure
708
     * @throws NotAuthorized
709
     * @throws NotFound
710
     * @throws NotImplemented
711
     * @throws InvalidRequest
712
     */
713
    private void describeObject(String pid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, InvalidRequest
714
    {
715
        response.setStatus(200);
716
        response.setContentType("text/xml");
717
        
718
        Identifier id = new Identifier();
719
        id.setValue(pid);
720

  
721
        DescribeResponse dr = CNodeService.getInstance(request).describe(session, id);
722
        //response.addHeader("pid", pid);
723
        response.addHeader("DataONE-Checksum", dr.getDataONE_Checksum().getAlgorithm() + "," + dr.getDataONE_Checksum().getValue());
724
        response.addHeader("Content-Length", dr.getContent_Length() + "");
725
        response.addHeader("Last-Modified", DateTimeMarshaller.serializeDateToUTC(dr.getLast_Modified()));
726
        response.addHeader("DataONE-ObjectFormat", dr.getDataONE_ObjectFormatIdentifier().getValue());
727
        response.addHeader("DataONE-SerialVersion", dr.getSerialVersion().toString());
728

  
729
    }
730

  
731
    /**
658 732
     * Return the requested object format
659 733
     * 
660 734
     * @param fmtidStr
......
839 913
        Subject subject = TypeMarshaller.unmarshalTypeFromStream(Subject.class,
840 914
                new ByteArrayInputStream(subjectStr.getBytes("UTF-8")));
841 915

  
842
        Identifier retPid = CNodeService.getInstance(request).setOwner(session,
843
                pid, subject, serialVersion);
916
        Identifier retPid = CNodeService.getInstance(request).setRightsHolder(session, pid, subject, serialVersion);
844 917
        OutputStream out = response.getOutputStream();
845 918
        response.setStatus(200);
846 919
        response.setContentType("text/xml");
src/edu/ucsb/nceas/metacat/util/MetacatPopulator.java
254 254
	              SystemMetadata resourceMapSysMeta = generateSystemMetadata(rmDoc);
255 255
	              mn.create(session, resourceMapId, IOUtils.toInputStream(resourceMapXML, MetaCatServlet.DEFAULT_ENCODING), resourceMapSysMeta);
256 256
	              
257
	              // clean up the permissions (FORCE public read)
258
	              for (Identifier dataId: dataIds) {
259
	            	  mn.setAccessPolicy(session, dataId, sysmeta.getAccessPolicy());
260
	            	  System.out.println("Set public access policy for: " + dataId.getValue());
261
	              }
262 257
            }
263 258
              
264 259
            }
src/edu/ucsb/nceas/metacat/dataone/ObjectFormatService.java
97 97
	 * @return objectFormat - the desired object format
98 98
	 */
99 99
	public ObjectFormat getFormat(ObjectFormatIdentifier fmtid)
100
			throws ServiceFailure, NotFound,
101
			InsufficientResources, NotImplemented {
100
			throws ServiceFailure, NotFound, NotImplemented {
102 101

  
103 102
		logMetacat.debug("CNCoreImpl.getFormat() called.");
104 103

  
......
129 128
	 * 
130 129
	 * @return objectFormatList - the list of object formats
131 130
	 */
132
	public ObjectFormatList listFormats() throws ServiceFailure, InsufficientResources, NotImplemented {
131
	public ObjectFormatList listFormats() throws ServiceFailure, NotImplemented {
133 132

  
134 133
		objectFormatList = getCachedList();
135 134

  
src/edu/ucsb/nceas/metacat/dataone/MNodeService.java
99 99
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
100 100
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService;
101 101
import edu.ucsb.nceas.metacat.properties.PropertyService;
102
import edu.ucsb.nceas.metacat.shared.ServiceException;
102 103
import edu.ucsb.nceas.metacat.util.SystemUtil;
103 104
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
104 105

  
......
587 588
    }
588 589

  
589 590
    /**
590
     * This method provides a lighter weight mechanism than 
591
     * MN_read.getSystemMetadata() for a client to determine basic 
592
     * properties of the referenced object.
593
     * 
594
     * @param session - the Session object containing the credentials for the Subject
595
     * @param pid - the identifier of the object to be described
596
     * 
597
     * @return describeResponse - A set of values providing a basic description 
598
     *                            of the object.
599
     * 
600
     * @throws InvalidToken
601
     * @throws ServiceFailure
602
     * @throws NotAuthorized
603
     * @throws NotFound
604
     * @throws NotImplemented
605
     * @throws InvalidRequest
606
     */
607
    @Override
608
    public DescribeResponse describe(Session session, Identifier pid) 
609
        throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented {
610

  
611
      // get system metadata and construct the describe response
612
        SystemMetadata sysmeta = getSystemMetadata(session, pid);
613
        DescribeResponse describeResponse = 
614
        	new DescribeResponse(sysmeta.getFormatId(), sysmeta.getSize(), 
615
        			sysmeta.getDateSysMetadataModified(),
616
        			sysmeta.getChecksum(), sysmeta.getSerialVersion());
617

  
618
        return describeResponse;
619

  
620
    }
621

  
622
    /**
623 591
     * Return the object identified by the given object identifier
624 592
     * 
625 593
     * @param session - the Session object containing the credentials for the Subject
......
818 786
            Ping canPing = new Ping();
819 787
            canPing.setSuccess(false);
820 788
            try {
821
                canPing.setSuccess(ping());
822
            } catch (InsufficientResources e) {
789
            	Date pingDate = ping();
790
                canPing.setSuccess(pingDate != null);
791
            } catch (BaseException e) {
823 792
                e.printStackTrace();
793
                // guess it can't be pinged
824 794
            }
825 795
            
826 796
            node.setPing(canPing);
......
955 925
    }
956 926

  
957 927
    /**
958
     * Low level “are you alive” operation. A valid ping response is 
959
     * indicated by a HTTP status of 200.
960
     * 
961
     * @return true if the service is alive
962
     * 
963
     * @throws InvalidToken
964
     * @throws ServiceFailure
965
     * @throws NotImplemented
966
     */
967
    @Override
968
    public boolean ping() 
969
        throws NotImplemented, ServiceFailure, InsufficientResources {
970

  
971
        // test if we can get a database connection
972
        boolean alive = false;
973
        int serialNumber = -1;
974
        DBConnection dbConn = null;
975
        try {
976
            dbConn = DBConnectionPool.getDBConnection("MNodeService.ping");
977
            serialNumber = dbConn.getCheckOutSerialNumber();
978
            alive = true;
979
        } catch (SQLException e) {
980
            return alive;
981
        } finally {
982
            // Return the database connection
983
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
984
        }
985

  
986
        return alive;
987
    }
988

  
989
    /**
990 928
     * A callback method used by a CN to indicate to a MN that it cannot 
991 929
     * complete synchronization of the science metadata identified by pid.  Log
992 930
     * the event in the metacat event log.
......
1111 1049
    }
1112 1050

  
1113 1051
    /**
1114
     * Set the access policy
1115
     */
1116
    @Deprecated
1117
    @Override
1118
    public boolean setAccessPolicy(Session session, Identifier pid,
1119
        AccessPolicy policy) 
1120
        throws InvalidToken, ServiceFailure, NotFound, NotAuthorized, 
1121
        NotImplemented, InvalidRequest {
1122
        
1123
        throw new NotImplemented("4401", "This method is deprecated for Member Nodes.");
1124
        
1125
    }
1126

  
1127
    /**
1128 1052
     * A method to notify the Member Node that the authoritative copy of 
1129 1053
     * system metadata on the Coordinating Nodes has changed.
1130 1054
     * 
src/edu/ucsb/nceas/metacat/dataone/CNodeService.java
52 52
import org.dataone.service.exceptions.UnsupportedType;
53 53
import org.dataone.service.types.v1.AccessPolicy;
54 54
import org.dataone.service.types.v1.Checksum;
55
import org.dataone.service.types.v1.ChecksumAlgorithmList;
55 56
import org.dataone.service.types.v1.Identifier;
56 57
import org.dataone.service.types.v1.Node;
57 58
import org.dataone.service.types.v1.NodeList;
......
598 599
   */
599 600
  @Override
600 601
  public ObjectFormat getFormat(ObjectFormatIdentifier fmtid)
601
    throws ServiceFailure, NotFound, InsufficientResources,
602
    NotImplemented {
602
    throws ServiceFailure, NotFound, NotImplemented {
603 603
     
604 604
      return ObjectFormatService.getInstance().getFormat(fmtid);
605 605
      
......
618 618
   */
619 619
  @Override
620 620
  public ObjectFormatList listFormats() 
621
    throws ServiceFailure, InsufficientResources, 
622
    NotImplemented {
621
    throws ServiceFailure, NotImplemented {
623 622

  
624 623
    return ObjectFormatService.getInstance().listFormats();
625 624
  }
......
801 800
   * @throws InvalidRequest
802 801
   */  
803 802
  @Override
804
  public Identifier setOwner(Session session, Identifier pid, Subject userId,
803
  public Identifier setRightsHolder(Session session, Identifier pid, Subject userId,
805 804
      long serialVersion)
806 805
      throws InvalidToken, ServiceFailure, NotFound, NotAuthorized,
807 806
      NotImplemented, InvalidRequest {
......
1258 1257

  
1259 1258
        return objectList;
1260 1259
  }
1260

  
1261
	@Override
1262
	public ChecksumAlgorithmList listChecksumAlgorithms()
1263
			throws ServiceFailure, NotImplemented {
1264
		ChecksumAlgorithmList cal = new ChecksumAlgorithmList();
1265
		cal.addAlgorithm("MD5");
1266
		cal.addAlgorithm("SHA-1");
1267
		return null;
1268
	}
1261 1269
    
1262 1270
}
src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java
57 57
import org.dataone.service.exceptions.UnsupportedType;
58 58
import org.dataone.service.types.v1.AccessPolicy;
59 59
import org.dataone.service.types.v1.AccessRule;
60
import org.dataone.service.types.v1.DescribeResponse;
60 61
import org.dataone.service.types.v1.Event;
61 62
import org.dataone.service.types.v1.Identifier;
62 63
import org.dataone.service.types.v1.Group;
......
79 80
import edu.ucsb.nceas.metacat.IdentifierManager;
80 81
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
81 82
import edu.ucsb.nceas.metacat.MetacatHandler;
83
import edu.ucsb.nceas.metacat.database.DBConnection;
84
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
82 85
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService;
83 86
import edu.ucsb.nceas.metacat.properties.PropertyService;
84 87
import edu.ucsb.nceas.metacat.replication.ForceReplicationHandler;
......
108 111
	}
109 112
  
110 113
  /**
114
   * This method provides a lighter weight mechanism than 
115
   * getSystemMetadata() for a client to determine basic 
116
   * properties of the referenced object.
117
   * 
118
   * @param session - the Session object containing the credentials for the Subject
119
   * @param pid - the identifier of the object to be described
120
   * 
121
   * @return describeResponse - A set of values providing a basic description 
122
   *                            of the object.
123
   * 
124
   * @throws InvalidToken
125
   * @throws ServiceFailure
126
   * @throws NotAuthorized
127
   * @throws NotFound
128
   * @throws NotImplemented
129
   * @throws InvalidRequest
130
   */
131
  public DescribeResponse describe(Session session, Identifier pid) 
132
      throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented {
133

  
134
    // get system metadata and construct the describe response
135
      SystemMetadata sysmeta = getSystemMetadata(session, pid);
136
      DescribeResponse describeResponse = 
137
      	new DescribeResponse(sysmeta.getFormatId(), sysmeta.getSize(), 
138
      			sysmeta.getDateSysMetadataModified(),
139
      			sysmeta.getChecksum(), sysmeta.getSerialVersion());
140

  
141
      return describeResponse;
142

  
143
  }
144
  
145
  /**
146
   * Low level, "are you alive" operation. A valid ping response is 
147
   * indicated by a HTTP status of 200.
148
   * 
149
   * @return true if the service is alive
150
   * 
151
   * @throws NotImplemented
152
   * @throws ServiceFailure
153
   * @throws InsufficientResources
154
   */
155
  public Date ping() 
156
      throws NotImplemented, ServiceFailure, InsufficientResources {
157

  
158
      // test if we can get a database connection
159
      int serialNumber = -1;
160
      DBConnection dbConn = null;
161
      try {
162
          dbConn = DBConnectionPool.getDBConnection("MNodeService.ping");
163
          serialNumber = dbConn.getCheckOutSerialNumber();
164
      } catch (SQLException e) {
165
      	ServiceFailure sf = new ServiceFailure("", e.getMessage());
166
      	sf.initCause(e);
167
          throw sf;
168
      } finally {
169
          // Return the database connection
170
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
171
      }
172

  
173
      return Calendar.getInstance().getTime();
174
  }
175
  
176
  /**
111 177
   * Adds a new object to the Node, where the object is either a data 
112 178
   * object or a science metadata object. This method is called by clients 
113 179
   * to create new data objects on Member Nodes or internally for Coordinating
src/edu/ucsb/nceas/metacat/admin/D1Admin.java
36 36
import org.dataone.client.CNode;
37 37
import org.dataone.client.D1Client;
38 38
import org.dataone.client.auth.CertificateManager;
39
import org.dataone.service.exceptions.BaseException;
39 40
import org.dataone.service.exceptions.IdentifierNotUnique;
40 41
import org.dataone.service.exceptions.InvalidRequest;
42
import org.dataone.service.exceptions.InvalidToken;
41 43
import org.dataone.service.exceptions.NotAuthorized;
42 44
import org.dataone.service.exceptions.NotFound;
43 45
import org.dataone.service.exceptions.NotImplemented;
......
354 356
	            PropertyService.setProperty("dataone.memberNodeId", mnodeRef.getValue());
355 357
	            
356 358
            }
357
        } catch (ServiceFailure e) {
359
        } catch (BaseException e) {
358 360
            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
359
        } catch (NotFound e) {
360
            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
361
        } catch (NotImplemented e) {
362
            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
363
        } catch (NotAuthorized e) {
364
            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
365
        } catch (InvalidRequest e) {
366
            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
367
        } catch (IdentifierNotUnique e) {
368
            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
369 361
        } catch (PropertyNotFoundException e) {
370 362
            logMetacat.warn("Could not find the location for client certificates: " + e.getMessage());
371 363
        } catch (GeneralPropertyException e) {

Also available in: Unified diff