/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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 org.apache.openmeetings.db.dto.room;

import java.util.HashMap;
import java.util.Map;

public class WhiteboardObjectList {

	private Long room_id;
	private Map<Long,WhiteboardObject> whiteboardObjects = new HashMap<Long,WhiteboardObject>();
	
	public Long getRoom_id() {
		return room_id;
	}
	public void setRoom_id(Long roomId) {
		room_id = roomId;
	}
	public Map<Long, WhiteboardObject> getWhiteboardObjects() {
		return whiteboardObjects;
	}
	public void setWhiteboardObjects(Map<Long, WhiteboardObject> whiteboardObjects) {
		this.whiteboardObjects = whiteboardObjects;
	}
	
}
