| /******************************************************************************* |
| * Copyright (c) 2004, 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.core.internal.registry; |
| |
| /** |
| * An object which has the general characteristics of all the nestable elements |
| * in a plug-in manifest. |
| */ |
| public abstract class RegistryObject implements KeyedElement { |
| //Object identifier |
| private int objectId = RegistryObjectManager.UNKNOWN; |
| //The children of the element |
| protected int[] children = RegistryObjectManager.EMPTY_INT_ARRAY; |
| |
| // The field combines offset, persistence flag, and no offset flag |
| private int extraDataOffset = EMPTY_MASK; |
| |
| // it is assumed that int has 32 bits (bits #0 to #31); |
| // bits #0 - #29 are the offset (limited to about 1Gb) |
| // bit #30 - persistance flag |
| // bit #31 - registry object has no extra data offset |
| // the bit#31 is a sign bit; bit#30 is the highest mantissa bit |
| static final int EMPTY_MASK = 0x80000000; // only taking bit #31 |
| static final int PERSIST_MASK = 0x40000000; // only taking bit #30 |
| static final int OFFSET_MASK = 0x3FFFFFFF; // all bits but #30, #31 |
| |
| //The registry that owns this object |
| protected ExtensionRegistry registry; |
| |
| protected RegistryObject(ExtensionRegistry registry, boolean persist) { |
| this.registry = registry; |
| setPersist(persist); |
| } |
| |
| void setRawChildren(int[] values) { |
| children = values; |
| } |
| |
| //This can not return null. It returns the singleton empty array or an array |
| protected int[] getRawChildren() { |
| return children; |
| } |
| |
| void setObjectId(int value) { |
| objectId = value; |
| } |
| |
| protected int getObjectId() { |
| return objectId; |
| } |
| |
| //Implementation of the KeyedElement interface |
| public int getKeyHashCode() { |
| return objectId; |
| } |
| |
| public Object getKey() { |
| return new Integer(objectId); |
| } |
| |
| public boolean compare(KeyedElement other) { |
| return objectId == ((RegistryObject) other).objectId; |
| } |
| |
| protected boolean shouldPersist() { |
| return (extraDataOffset & PERSIST_MASK) == PERSIST_MASK; |
| } |
| |
| private void setPersist(boolean persist) { |
| if (persist) |
| extraDataOffset |= PERSIST_MASK; |
| else |
| extraDataOffset &= ~PERSIST_MASK; |
| } |
| |
| protected boolean noExtraData() { |
| return (extraDataOffset & EMPTY_MASK) == EMPTY_MASK; |
| } |
| |
| // Convert no extra data to -1 on output |
| protected int getExtraDataOffset() { |
| if (noExtraData()) |
| return -1; |
| return extraDataOffset & OFFSET_MASK; |
| } |
| |
| // Accept -1 as "no extra data" on input |
| protected void setExtraDataOffset(int offset) { |
| if (offset == -1) { |
| extraDataOffset &= ~OFFSET_MASK; // clear all offset bits |
| extraDataOffset |= EMPTY_MASK; |
| return; |
| } |
| |
| if ((offset & OFFSET_MASK) != offset) |
| throw new IllegalArgumentException("Registry object: extra data offset is out of range"); //$NON-NLS-1$ |
| |
| extraDataOffset &= ~(OFFSET_MASK | EMPTY_MASK); // clear all offset bits; mark as non-empty |
| extraDataOffset |= (offset & OFFSET_MASK); // set all offset bits |
| } |
| |
| protected String getLocale() { |
| return registry.getLocale(); |
| } |
| } |